#include "ResourceManager.h"
#include "Database/DatabaseEnv.h"
#include "StringConverter.h"
#include "json/json.h"
#include "NGLog.h"
#include "Character.h"
#include "CharManager.h"
#include "Items.h"
#include "ItemManager.h"
#include "Users.h"
#include "UserManager.h"
#include "ChannelManager.h"
#include "ItemModelManager.h"
#include "Message.h"
#include "CenterBankManager.h"
#include "VipCardManager.h"
#include "Tools.h"
#include "XMLData.h"
#include LOGIC_MGR_PATH
#include LOG_MGR_PATH
#include PROTOCOLS_MGR_PATH
#include "OpcodesEx.h"
#include "CenterBattleManager.h"
#ifdef ENUM_PATH
	#include ENUM_PATH
#else
	#include "GameDataEnum.h"
#endif
#include "WSSocket.h"
#include "ProtocolDealEnums.h"

#define FKTHIS_TIME	1344047400
#define GAME_TYPE 1	// 银行
#define PUBLIC_TYPE 2	// 公共数据存储
#define LEMA_LOG_TYPE 11	// 乐码日志类型
#define DEFAULT_ITEM_LIST 1000	// 默认物品配置

String GetUTF8String(String &str)
{
	if (StringUtil::checkStringUTF8(str))
		return str;
	return StringUtil::StringToUTF8(str);
}

//-----------------------------------------------
CenterBankManager::CenterBankManager()
{
	LoadFieldXml();
}

//-----------------------------------------------
CenterBankManager::~CenterBankManager()
{
	
}

#define SQLBUFER_LEN 16384
bool CenterBankManager::UpdateCenterBank(Fields * fields, const char * QueryString, ...)
{
	char sql[SQLBUFER_LEN] = ""; 
	va_list vlist; 
	va_start(vlist, QueryString); 
	vsnprintf(sql, SQLBUFER_LEN, QueryString, vlist); 
	va_end(vlist);
	int count = sDataMgr.updateDataQueryAffected(DataManager::DatabaseTypeCenter, "game_bank", fields, sql);
	Log.Debug("CenterBankManager::UpdateCenterBank","count[%u]", count);
	return count > 0;
}

//-----------------------------------------------------------------------
uint64 CenterBankManager::GetCenterBankWealth(CharPtr &pChr, const uint32 modelId)
{
	if (pChr.isNull() || !modelId)
		return 0;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	return GetCenterBankWealth(pUser, modelId);
}

uint64 CenterBankManager::GetCenterBankWealth(UserPtr &pUser, const uint32 modelId)
{
	if (pUser.isNull() || !modelId)
		return 0;
	uint64 mySave = 0;
	GameBank bank;
	if (GetRealBank(pUser, bank))
	{
		switch (modelId)
		{
			case en_ItemModelId_Coins: // 铜钱
				mySave = bank.coins;
				break;
			default:
				mySave = 0;
				break;
		}
	}
	return mySave;
}
//-----------------------------------------------------------------------
bool CenterBankManager::SaveWealthInBank(UserPtr &pUser, const uint32 modelId, const uint32 num, const uint8 & optype)
{
	if (pUser.isNull() || !modelId || !num)
		return false;
	GameBank bank;
	if (!GetRealBank(pUser, bank))
		return false;
	uint64 orgNum = 0;
	String pField = "";
	switch (modelId)
	{
		case en_ItemModelId_Coins:// 铜钱
			orgNum = bank.coins;
			pField = "coins";
			break;
		default:
			return false;
	}
	if (CenterDatabase.WaitExecute("update game_bank set `%s` = %u, `last_time` = %u where bank_id = %u and `%s` = %u", 
						pField.c_str(), orgNum + num, time(0), bank.bank_id, pField.c_str(), orgNum))
	{
		SaveAndGetWealthLog(pUser, optype, modelId, num, orgNum + num);
		return true;
	}
	else
		return false;
}
//-----------------------------------------------------------------------
bool CenterBankManager::GetWealthFromBank(UserPtr &pUser, const uint32 modelId, const uint32 num, const uint8 & optype)
{
	if (pUser.isNull() || !modelId || !num)
		return 0;
	GameBank bank;
	if (!GetRealBank(pUser, bank))
		return false;
	uint64 orgNum = 0;
	String pField = "";
	switch (modelId)
	{
		case en_ItemModelId_Coins:// 铜钱
			orgNum = bank.coins;
			pField = "coins";
			break;
		default:
			return false;
	}
	if (orgNum < num)
		return false;
	if (CenterDatabase.WaitExecute("update game_bank set `%s` = %u, `last_time` = %u where bank_id = %u and `%s` = %u", pField.c_str(), orgNum - num, time(0), bank.bank_id, pField.c_str(), orgNum))
	{
		// 记录日志
		SaveAndGetWealthLog(pUser, optype, modelId, num, orgNum - num);
		return true;
	}
	else
		return false;
}

//-----------------------------------------------------------------------
bool CenterBankManager::GetRealBank(UserPtr &pUser, GameBank &bank)
{
	if (pUser.isNull() || 0 == pUser->getUInt32Field("platform_id"))
		return false;
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE))
	{
		// 创建
		if (!AddBankInfo(pUser))
			return false;
		if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE))
			return false;
	}
	std::list<GameBank>::iterator iter = lstBankInfo.begin();
	if ((*iter).link_id)
	{
		if (!sChannelMgr.getBankDB((*iter).link_id, &bank))
			return false;
	}
	else
	{
		bank = *iter;
	}
	
	if(bank.nick != pUser->getStringField("nick"))
	{// 昵称发生变化修改玩家银行昵称
		bank.nick = pUser->getStringField("nick");
		// CenterDatabase.WaitExecute("update game_bank set `nick` = '%s' where bank_id = %u", bank.nick.c_str(), bank.bank_id);
		sChannelMgr.updateBankDB(&bank);
	}
	
	return true;
}

uint8 CenterBankManager::GetRealBank(const uint32 & pid, GameBank &bank)
{
	if (pid == 0)
		return enGetPlayerInfoByPid_NoUseID;
	
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pid, GAME_TYPE))
		return enGetPlayerInfoByPid_NotExistID;
	
	std::list<GameBank>::iterator iter = lstBankInfo.begin();
	if ((*iter).link_id)
	{
		if (!sChannelMgr.getBankDB((*iter).link_id, &bank))
			return enGetPlayerInfoByPid_NotExistID;
	}
	else
		bank = *iter;
	
	return enGetPlayerInfoByPid_Sucess;
}

//-----------------------------------------------------------------------
bool CenterBankManager::ExistBank(UserPtr & pUser)
{
	if (pUser.isNull() || 0 == pUser->getUInt32Field("platform_id"))
		return false;
	std::list<GameBank> lstBankInfo;
	return sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE);
}

//-----------------------------------------------------------------------
bool CenterBankManager::SetPassworld(UserPtr & pUser, const String & pwd)
{
	if(pUser.isNull())
		return false;
		
	GameBank bank;
	if (GetRealBank(pUser, bank))
	{
		bank.sdata1 = pwd;
		return CenterDatabase.WaitExecute("update game_bank set `sdata1`= '%s' where bank_id = %u", bank.sdata1.c_str(), bank.bank_id);
	}
	
	return false;
}

//-----------------------------------------------------------------------
String CenterBankManager::GetPassworld(UserPtr & pUser)
{
	if(pUser.isNull())
		return "";
	
	GameBank bank;
	if(GetRealBank(pUser, bank))
	{
		if(bank.sdata1 == "")
		{
			bank.sdata1 = DEFAULT_PASSWORLD;
			CenterDatabase.WaitExecute("update game_bank set `sdata1` = '%s' where bank_id = %u", bank.sdata1.c_str(), bank.bank_id);
			return bank.sdata1;
		}
		
		return bank.sdata1;
	}
	
	return "";
}

//-----------------------------------------------------------------------
void CenterBankManager::ResetPassworld(UserPtr & pUser)
{
	if(pUser.isNull())
		return;
	
	GameBank bank;
	if(GetRealBank(pUser, bank))
	{
		bank.sdata1 = DEFAULT_PASSWORLD;
		CenterDatabase.WaitExecute("update game_bank set `sdata1` = '%s' where bank_id = %u", bank.sdata1.c_str(), bank.bank_id);	
	}
}

//-----------------------------------------------------------------------
void CenterBankManager::CopyPassworld(UserPtr & pUser)
{
	if(pUser.isNull())
		return;
	
	if(pUser->getUInt32Field("flag"))
		return;
	
	if (!sChannelMgr.getBankDBCount("`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE))
		return;
	
	std::list<GameBank> lstBankInfo;
	if(sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE))
	{
		if(lstBankInfo.empty())
			return;
			
		GameBank bank = lstBankInfo.front();
		
	}
}

//-----------------------------------------------------------------------
uint64 CenterBankManager::AddBankInfo(UserPtr &pUser, GameBank *pGameBank)
{
	if (pUser.isNull() || 0 == pUser->getUInt32Field("platform_id"))
		return false;
	
	uint64 bankid = 0;
	if (!sChannelMgr.getBankDBCount("`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE))
	{
		GameBank *pBank = sChannelMgr.newDumyBank();
		if (pBank)
		{
			pBank->platform_id = pUser->getUInt32Field("platform_id");
			pBank->gz_id = pUser->getUInt32Field("gz_id");
			pBank->game_id = pUser->getUInt32Field("gz_id");
			pBank->type = GAME_TYPE;
			pBank->status = BankStatusFree;
			pBank->uid = pUser->getHandle();
			pBank->name = pUser->getStringField("name");
			pBank->nick = pUser->getStringField("nick");
			pBank->sdata1 = DEFAULT_PASSWORLD;
			
			bankid = sChannelMgr.addBankDB(pBank);
			
			if(pGameBank != NULL)
			{
				*pGameBank = *pBank;
				pGameBank->bank_id = bankid;
			}
		}
		sChannelMgr.freeDumyBank(pBank);
	}
	Log.Debug("CenterBankManager::AddBankInfo","bankid[%u]", bankid);
	return bankid;
}
//-----------------------------------------------------------------------
bool CenterBankManager::BandFatherBank(UserPtr &pUser, const uint32 platformId)
{
	if (pUser.isNull() || 0 == pUser->getUInt32Field("platform_id"))
		return false;
	std::list<GameBank> lstBankInfo;
	sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE);
	GameBank &bank = *lstBankInfo.begin();
	if (!lstBankInfo.empty() && 0 == bank.link_id)
	{
		// 自身不是父级
		uint32 count = sChannelMgr.getBankDBCount("`link_id` = %u", bank.bank_id);
		if (count)
			return false;
		// 父级是否已包含相同分区
		std::list<GameBank> lstBankInfo1;
		sChannelMgr.getBankList(&lstBankInfo1, 0, 1, "`platform_id` = %u and `type` = %u", platformId, GAME_TYPE);
		if (!lstBankInfo1.empty())
		{
			// GameBank &bank1 = *lstBankInfo1.begin();
			
		}
	}
	return false;
}
//-----------------------------------------------------------------------
void CenterBankManager::SaveAndGetWealthLog(UserPtr &pUser, const uint32 operate, const uint32 modelId, const uint32 num, const uint32 curNum)
{
	if (pUser.isNull())
		return;
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if (pLog)
	{
		// 填充日志信息
		pLog->status = 1;
		// 1：存 2：取
		pLog->type = operate; 
		// pid
		pLog->src_id = pUser->getUInt32Field("platform_id");
		// 分区
		pLog->dest_id = pUser->getUInt32Field("gz_id");
		// 用户ID
		pLog->target_id = pUser->getHandle();
		// 物品ID
		pLog->data1 = modelId;
		// 数量
		pLog->data2 = num;
		// 该物品在银行余额
		pLog->data3 = curNum;
		char strDesc[256];
		String opStr = "存入";
		if(operate == en_Operate_Get)
			opStr = "取出";
		else if(operate == en_Operate_GiveItem)
			opStr = "获赠";
		
		sprintf(strDesc, "PID为【%u】的玩家在【%u】分区从银行【%s】【%u】模式ID为【%u】的物品，当前余额【%u】，用户ID为【%u】", pLog->src_id, pLog->dest_id, 
				opStr.c_str(), num, modelId, curNum, pLog->target_id);
		String strInfo(strDesc);
		pLog->info = GetUTF8String(strInfo);
		pLog->create_time = sTools.GetCurDateTime();
		sChannelMgr.addCenterLogDB(pLog);
	}
	sChannelMgr.freeDumyCenterLog(pLog);
}

//-----------------------------------------------------------------------
bool 	CenterBankManager::JoinGameServer(UserPtr & pUser, const uint16 & theserverid, uint16 *currgid /* = NULL */)
{
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	if(pChr->getStatus() != CharacterStatusFree)
		return true;
WGS_DATABUFF_INNER_LOCK
	GameBank bank;
	std::list<GameBank> lstBankInfo;
	sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE);
	if(lstBankInfo.empty())
	{// 非正常流程
		return true;
	}
	
	bank = lstBankInfo.front();
	Log.Debug("CenterBankManager", "JoinGameServer pChr[%u] Comein Server[%u] server_start_time[%u] bank status[%u]", 
							pChr->getHandle(), theserverid, system_start_time_t,bank.status);
	
	if (currgid != NULL)	
		*currgid = bank.gz_id;
	
	if(pUser->getUInt32Field("flag") == 0 && bank.sdata1 == "")
	{// 设置银行安全密码
		bank.sdata1 = pUser->getStringField("passwd2");
		CenterDatabase.WaitExecute("update game_bank set `sdata1` = '%s' where bank_id = %u", bank.sdata1.c_str(), bank.bank_id);
	}
	
	// 把旧的状态转成新的状态
	switch(bank.status)
	{
		case BankStatusLogined:
		{
			bank.status = BankStatusFree;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusFree, bank.bank_id);
			break;
		}
		case BankStatusLogouting:
		{
			bank.status = BankStatusStart;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusStart, bank.bank_id);
			break;
		}
		case BankStatusLogoutData:
		{
			bank.status = BankStatusStartData;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusStartData, bank.bank_id);
			break;
		}
		case BankStatusLogouted:
		{
			bank.status = BankStatusPrep;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusPrep, bank.bank_id);
			break;
		}
		case BankStatusCompose:
		{
			bank.status = BankStatusStart;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusStart, bank.bank_id);
			break;
		}
		/* case BankStatusLoging:
		{// 如果有出错，马上屏蔽这里
			bank.status = BankStatusPrep;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusPrep, bank.bank_id);
			break;
		}
		case BankStatusStart:
		{// 如果有出错，马上屏蔽这里
			bank.status = BankStatusPrep;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusPrep, bank.bank_id);
			break;
		} */
		default:
			break;
	}
	
	if(bank.status == BankStatusPrep)
	{
		WhereaboutsLog(pUser, 0, theserverid, &bank);
		// SetBankDataFlag(pChr);	
		// Log.Debug("CenterBankManager Test", "///////JoinGameServer pChr[%u] bank.status[%u] aaa",pChr->getHandle(), bank.status);
		if(!updateBankStatusDB(bank, BankStatusLoging, BankStatusPrep))
		{
			Log.Error("CenterBankManager::JoinGameServer", "update change bank[%u] status to BankStatusLoging Error! currStatus[%u]", 
					bank.bank_id, bank.status);
			return false;				
		}
		Log.Debug("CenterBankManager Test", "///////JoinGameServer pChr[%u] bank.status[%u] gz_id[%u]",pChr->getHandle(), bank.status, bank.gz_id);
		// 拷贝
		OutputBankBuffer(pChr, theserverid, bank, BankStatusLoging, true);
		if (currgid != NULL)	
			*currgid = bank.gz_id;
		
		// Log.Debug("CenterBankManager Test", "///////JoinGameServer pChr[%u] bank.status[%u] ccc",pChr->getHandle(), bank.status);
		return true;
	}
	return true;
}

//-----------------------------------------------------------------------
bool 	CenterBankManager::LeaveGameServer(UserPtr & pUser, const uint16 & thegid, const uint16 & destid)
{
	CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	
	if(pChr->getStatus() != CharacterStatusFree)
	{
		Log.Error("CenterBankManager::LeaveGameServer","pChr[%u] status[%u] error!", pChr->getHandle(), pChr->getStatus());
		return false;
	}
	
	if (!IsGameExist(pChr->getUInt32Field("gz_id")))
	{
		Log.Error("CenterBankManager::LeaveGameServer","pChr[%u] in error gz_id[%u]!", pChr->getHandle(), pChr->getUInt32Field("gz_id"));
		return false;
	}
	
	if (pChr->isFreezeDB())
	{
		Log.Debug("CenterBankManager::LeaveGameServer","LeaveGameServer pChr[%u] is Faild!", pChr->getHandle());
		return false;
	}
	
WGS_DATABUFF_INNER_LOCK
	GameBank bank;
	std::list<GameBank> lstBankInfo;
	sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE);
	if(lstBankInfo.empty())
	{// 非正常流程退出,暂不处理	
		if(!AddBankInfo(pUser, &bank))
		{
			return false;
		}
	}
	else
	{	
		bank = lstBankInfo.front();
	}
	
	Log.Warning("CenterBankManager::LeaveGameServer","pChr[%u] char status[%u] bank status[%u] 111", pChr->getHandle(), pChr->getStatus(), bank.status);
	switch(bank.status)
	{
		case BankStatusLogined:
		{
			bank.status = BankStatusFree;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusFree, bank.bank_id);
			break;
		}
		case BankStatusLogouting:
		{
			bank.status = BankStatusStart;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusStart, bank.bank_id);
			break;
		}
		case BankStatusLogoutData:
		{
			bank.status = BankStatusStartData;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusStartData, bank.bank_id);
			break;
		}
		case BankStatusLogouted:
		{
			bank.status = BankStatusPrep;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusPrep, bank.bank_id);
			break;
		}
		case BankStatusCompose:
		{
			bank.status = BankStatusStart;
			CenterDatabase.WaitExecute("update game_bank set `status` = '%u' where bank_id = %u", BankStatusStart, bank.bank_id);
			break;
		}
		default:
			break;
	}
	Log.Warning("CenterBankManager::LeaveGameServer","pChr[%u] char status[%u] bank status[%u] 222", pChr->getHandle(), pChr->getStatus(), bank.status);
	if (bank.gz_id && thegid != bank.gz_id)
	{// 没在本游戏内，不执行退出操作
		Log.Error("CenterBankManager::LeaveGameServer", "LeaveGameServer ishere error! user[%u] ishere[%u] gz_id[%u]", 
			pUser->getHandle(), pChr->getUInt32Field("gz_id"), bank.gz_id);
		return false;
	}
	
	if(bank.status == BankStatusFree)
	{// 离开中心
		// SetBankDataFlag(pChr);		
		
		if(!updateBankStatusDB(bank, BankStatusStart, BankStatusFree))
			return false;		
			
		// 拷贝
		InputBankBuffer(pChr, thegid, bank, BankStatusStart, true);	
		
		WhereaboutsLog(pUser, 1, thegid, &bank);
					
		pChr->setUInt32Field("ishere", 0);
		pChr->SaveDB();
		Log.Debug("CenterBankManager Test", "///////LeaveGameServer pChr[%u] bank.status[%u] aaa", bank.status);
		
		// 给点时间处理数据更新
		Sleep(500);
		return true;
	}
	
	return false;		
}

bool 	CenterBankManager::DisconnectServer(UserPtr & pUser, const uint16 & mygid)
{
	if(pUser.isNull() || mygid == 0)
		return false;
	if(pUser->getUInt32Field("flag") != 1)
		return false;	
	Log.Debug("CenterBankManager Test","DisconnectServer pUser[%u] mygid[%u] flag[%u]", 
		pUser->getHandle(), mygid, pUser->getUInt32Field("flag"));
	return LeaveGameServer(pUser, mygid);
}

//--------------------------------------------------------
bool 	CenterBankManager::UpdateBankBuffDB(const GameBank & bank, const uint32 &laststatus)
{
	int count = CenterDatabase.WaitExecuteAffected("update game_bank set `game_id`=%u, `status`=%u, `data1`=%u, `data2`=%u, `data3`=%u, `data4`=%u, `data5`=%d, \
				`item1`=%u,`item2`=%u,`item3`=%u, `item4`=%u, `item8`=%u, `item9`=%u, `item10`=%u, `item11`=%u, `item12`=%u, `item13`=%u, `item14`=%u,`item15`=%u,`item17`=%u,`item18`=%u,`item19`=%u,`item20`=%u, \
				`sdata4` = '%s', `user_data`='%s', `gz_id` = %u, `src_gz_id` = %u, `last_time` = %u where bank_id = %u AND `status`=%u", \
					bank.game_id, bank.status, bank.data1, bank.data2, bank.data3, bank.data4, bank.data5,
				bank.item1,bank.item2,bank.item3, bank.item4, bank.item8, bank.item9, bank.item10, bank.item11, bank.item12, bank.item13, bank.item14, bank.item15, bank.item17, bank.item18, bank.item19, bank.item20,
								 bank.sdata4.c_str(), bank.user_data.c_str(), bank.gz_id, bank.src_gz_id, time(0), bank.bank_id, laststatus);
	Log.Debug("CenterBankManager Test", "UpdateBankBuffDB count[%d]", count);
	return count > 0;
	// std::list<GameBank> lstBankInfo;
	// sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`bank_id` = %u AND `status`=%u", bank.bank_id, bank.status);
	// assert(!lstBankInfo.empty());
	// return true;
}

//--------------------------------------------------------
void 	CenterBankManager::LoadFieldXml(void)
{
	TiXmlDocument doc("../scripts_xml/serverdata.xml");
	if(!doc.LoadFile())
	{
		Log.Error("load XML Error", "load serverdata.xml failed!");
		return ;
	}
	TiXmlElement* pRoot = doc.RootElement();
	if (NULL == pRoot)
	{
		Log.Error("load Xml Error", "serverdata.xml have not root node!");
		return ;
	}
	
	while(pRoot)
	{
		uint32 gid = 0;
		sscanf(pRoot->Value(), "gameid_%u", &gid);
		FieldNameList lstMatch;
		TiXmlElement* child = pRoot->FirstChildElement();
		while(child)
		{
			FieldName fn;
			fn.modelid = StringConverter::parseUnsignedInt(child->Attribute("model"));
			fn.field = child->Attribute("field");
			
			lstMatch.push_back(fn);
			child = child->NextSiblingElement();			
		}
		
		m_mapFieldName.insert(std::make_pair(gid, lstMatch));		
		pRoot = pRoot->NextSiblingElement();
	}
	
	Log.Debug("CenterBankManager::LoadFieldXml", "load serverdata.xml successfully!");
}

//--------------------------------------------------------
const String *CenterBankManager::GetFieldName(const uint16 & gid, const uint32 & modelid)
{
	std::map<uint16, FieldNameList>::iterator iter = m_mapFieldName.find(gid);
	if(iter == m_mapFieldName.end())
	{
		// 使用通用配置
		iter = m_mapFieldName.find(DEFAULT_ITEM_LIST);
		if (iter == m_mapFieldName.end())
		{
			return NULL;
		}
	}
	
	ItemModelPtr pModel = sItemModelMgr.load(modelid);
	if (pModel.isNull())
		return NULL;
	
	FieldNameList::iterator ii, endii = iter->second.end();
	for(ii = iter->second.begin(); ii != endii; ++ ii)
	{
		if((*ii).modelid == modelid)
		{
			return &(*ii).field;
		}
	}
	
	return NULL;
}

//--------------------------------------------------------
bool 	CenterBankManager::IsGameExist(const uint32 & gid)
{
	std::map<uint16, FieldNameList>::iterator iter = m_mapFieldName.find(gid);
	if(iter == m_mapFieldName.end())
	{
		iter = m_mapFieldName.find(DEFAULT_ITEM_LIST);
		if (iter == m_mapFieldName.end())
			return false;
	}
	
	return true;
}

//--------------------------------------------------------
void 	CenterBankManager::SetItemNum(const uint16 & thegid, CharPtr & pChr, const uint32 & modelid, const uint32 & num)
{
	if(pChr.isNull() || modelid == 0)
		return ;
	const String *field = GetFieldName(thegid, modelid);	
	if (field == NULL)
		return;
	
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid)
		{
			(*ii)->setUInt32Field("num", num);			
			(*ii)->SaveDB();
			break;
		}
	}	
	
	if(*field != "")
	{	
		pChr->setUInt32Field(*field, num);	
	}
}

//--------------------------------------------------------
bool 	CenterBankManager::SetSafeItemNum(const uint16 & thegid, CharPtr & pChr, const uint32 & modelid, const uint32 & num)
{
	if(pChr.isNull() || modelid == 0)
		return false;
	const String *field = GetFieldName(thegid, modelid);
	if (field == NULL)
		return false;
	
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid && (*ii)->getUInt32Field("flag") == BankItemPrep)
		{
			(*ii)->setUInt32Field("flag", BankItemFree);
			(*ii)->setUInt32Field("num", num);	
			(*ii)->setUInt32Field("attribute_ext", 0);				
			if(*field != "")
				pChr->setUInt32Field(*field, num);	
			(*ii)->SaveDB();
			return true;
		}
	}
	
	return false;
}

void 	CenterBankManager::SetBankSafeItemNum(GameBank & bank, const uint32 & modelid, const uint32 & num)
{
	switch (modelid)
	{
		case en_ItemModelId_Coins:
		{
			bank.data1 = num;
			break;
		}
		case en_ItemModelId_Exchange:
		{
			bank.data2 = num;
			break;
		}
		case en_ItemModelId_Gold:
		{
			bank.data3 = num;
			break;
		}
		case en_ItemModelId_Match:
		{
			bank.data4 = num;
			break;
		}
		case en_ItemModelId_Money:
		{
			bank.item1 = num;
			break;
		}
		case en_ItemModelId_Token:
		{
			bank.item2 = num;
			break;
		}
		case en_ItemModelId_Score:
		{
			bank.item3 = num;
			break;
		}
		case en_ItemModelId_BuQianKa:
		{
			bank.item4 = num;
			break;
		}
		case en_ItemModelId_GoldTicket:
		{
			bank.item8 = num;
			break;
		}
		case en_ItemModelId_DiamondOpen:
		{
			bank.item9 = num;
			break;
		}
		case ItemModel_LingGouBi:
		{
			bank.item10 = num;
			break;
		}
		case en_ItemModelId_Bugle:
		{
			bank.item11 = num;
			break;
		}
		case en_ItemModelId_Mammon:
		{
			bank.item12 = num;
			break;
		}
		case en_ItemModelId_Mammon2:
		{
			bank.item13 = num;
			break;
		}
		case en_ItemModelId_Diamond:
		{
			bank.item14 = num;
			break;
		}
		case en_ItemModelId_Diamond2:
		{
			bank.item15 = num;
			break;
		}
		case en_ItemModelId_Luck:
		{
			bank.item17 = num;
			break;
		}
		case en_ItemModelId_Luck2:
		{
			bank.item18 = num;
			break;
		}
		case en_ItemModelId_Luck3:
		{
			bank.item19 = num;
			break;
		}
		case en_ItemModelId_Subsidy:
		{
			bank.item20 = num;
			break;
		}
		default:
			break;
	}	
}

bool 	CenterBankManager::GetSafeItemNum(CharPtr & pChr, const uint32 & modelid, uint32 * num)
{
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid)
		{
			*num = (*ii)->getUInt32Field("attribute_ext");
			return true;
		}
	}
	
	*num = 0;
	return false;
}

uint32  CenterBankManager::GetBankSafeItemNum(GameBank & bank, const uint32 & modelid)
{
	switch (modelid)
	{
	case en_ItemModelId_Coins:
		return bank.data1;
	case en_ItemModelId_Exchange:
		return bank.data2;
	case en_ItemModelId_Gold:
		return bank.data3;
	case en_ItemModelId_Match:
		return bank.data4;
	case en_ItemModelId_Bugle:
		return bank.item11;
	case en_ItemModelId_Money:
		return bank.item1;
	case en_ItemModelId_Token:
		return bank.item2;
	case en_ItemModelId_Score:
		return bank.item3;
	case en_ItemModelId_BuQianKa:
		return bank.item4;
	case en_ItemModelId_GoldTicket:
		return bank.item8;
	case en_ItemModelId_DiamondOpen:
		return bank.item9;
	case ItemModel_LingGouBi:
		return bank.item10;
	case en_ItemModelId_Mammon:
		return bank.item12;
	case en_ItemModelId_Mammon2:
		return bank.item13;
	case en_ItemModelId_Diamond:
		return bank.item14;
	case en_ItemModelId_Diamond2:
		return bank.item15;
	case en_ItemModelId_Luck:
		return bank.item17;
	case en_ItemModelId_Luck2:
		return bank.item18;
	case en_ItemModelId_Luck3:
		return bank.item19;
	case en_ItemModelId_Subsidy:
		return bank.item20;
	default:
		break;			
	}
	
	return 0;
}

//--------------------------------------------------------
bool 	CenterBankManager::GetItemNum(CharPtr & pChr, const uint32 & modelid, uint32 * num)
{
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid)
		{
			*num = (*ii)->getUInt32Field("num");
			return true;
		}
	}
	
	*num = 0;
	return false;
}

//--------------------------------------------------------
void 	CenterBankManager::addItemNum(const uint16 & thegid, CharPtr & pChr, const uint32 & modelid, const uint32 & num)
{
	if(pChr.isNull() || modelid == 0)
		return ;
	const String *field = GetFieldName(thegid, modelid);
	if (field == NULL)
		return;
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid)
		{
			(*ii)->setUInt32Field("num", (*ii)->getUInt32Field("num") + num);			
			(*ii)->SaveDB();			
			if(*field != "")
			{	
				pChr->setUInt32Field(*field, (*ii)->getUInt32Field("num"));	
			}
			
			return;
		}
	}	
	
	CreateItem(pChr, modelid, num);
}

void 	CenterBankManager::addSafeItemNum(const uint16 & thegid, CharPtr & pChr, const uint32 & modelid, const uint32 & num)
{
	if(pChr.isNull() || modelid == 0)
		return ;
	const String *field = GetFieldName(thegid, modelid);
	if (field == NULL)
		return;
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid && (*ii)->getUInt32Field("flag") == BankItemPrep)
		{
			(*ii)->setUInt32Field("flag", BankItemFree);
			(*ii)->setUInt32Field("num", (*ii)->getUInt32Field("num") + num + (*ii)->getUInt32Field("attribute_ext"));	
			(*ii)->setUInt32Field("attribute_ext", 0);
			if(*field != "")
				pChr->setUInt32Field(*field, (*ii)->getUInt32Field("num"));	
			(*ii)->SaveDB();
			return;
		}
	}
	
	CreateItem(pChr, modelid, num);
}

//--------------------------------------------------------
void 	CenterBankManager::ReloadFieldXML(void)
{
	m_mapFieldName.clear();
	LoadFieldXml();
}

//--------------------------------------------------------
void CenterBankManager::WhereaboutsLog(UserPtr &pUser, const uint8 & type, const uint8 & where, const GameBank * pBank)
{
	if(pUser.isNull())
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	
	pLog->status = 1;
	pLog->type = en_Operate_Buff;
	pLog->src_id= pUser->getUInt32Field("platform_id");
	pLog->dest_id = where;
	pLog->dest_type = pBank->game_id;
	
	pLog->data1 = pBank->data1;
	pLog->data2 = pBank->data2;
	pLog->data3 = pBank->data3;
	pLog->data4 = pBank->data4;
	pLog->data5 = pBank->item11;
	pLog->data6 = pBank->item12;
	pLog->data7 = pBank->item20;
	
	pLog->data8 = pBank->status;
	pLog->user_data = pBank->user_data;
	
	pLog->sdata1 = pUser->getStringField("nick");
	// String gname = GetUTF8String(sXmlDataMgr.GetGzIdName(where));
	String szOp = type ? "游戏到缓存 " : "缓存到游戏 ";
	String szInfo = "玩家PID:";
	szInfo += StringConverter::toString(pLog->src_id);	
	szInfo += "在" + StringConverter::toString(where) + "游戏";
	szInfo += szOp;	
	szInfo += " 携带：" + StringConverter::toString(pBank->data1) + "铜钱," \
		+StringConverter::toString(pBank->data2) + "兑换券," \
		+ StringConverter::toString(pBank->item12) + "财神卡,"\
		+ StringConverter::toString(pBank->item17) + "小幸运,"\
		+ StringConverter::toString(pBank->item18) + "大幸运,"\
		+ StringConverter::toString(pBank->item19) + "超幸运,"\
		+ StringConverter::toString(pBank->item2) + "乐币,"\
		+ StringConverter::toString(pBank->item3) + "积分"\
		+ StringConverter::toString(pBank->item4) + "补签卡"\
		+ StringConverter::toString(pBank->item11) + "喇叭,"\
		+ StringConverter::toString(pBank->item20) + "救济卡";
		

	pLog->info = GetUTF8String(szInfo);
	pLog->create_time = sTools.GetCurDateTime();
	sChannelMgr.addCenterLogDB(pLog);
	sChannelMgr.freeDumyCenterLog(pLog);
}

bool 	CenterBankManager::updateBankStatusDB(GameBank & bank, const uint8 & nextstatus, const uint8 & backstatus)
{
	int count = CenterDatabase.WaitExecuteAffected("update game_bank set `status`=%u, `data6`=%u where `bank_id` = %u AND `status` = %u", nextstatus, system_start_time_t, bank.bank_id, backstatus);
	// Log.Debug("CenterBankManager Test", "updateBankStatusDB count[%d]", count);
	return count > 0;
	// if(CenterDatabase.WaitExecuteAffected("update game_bank set `status`=%u, `data6`=%u where `bank_id` = %u AND `status` = %u", nextstatus, system_start_time_t, bank.bank_id, backstatus))
	// {
		// std::list<GameBank> lstBankInfo;
		// sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`bank_id` = %u AND `status`=%u", bank.bank_id, nextstatus);
		// assert(!lstBankInfo.empty());
		// bank.status = nextstatus;
		// return true;
	// }
	// return false;
}

void 	CenterBankManager::updateBankGzidDB(GameBank & bank)
{
	CenterDatabase.WaitExecute("update game_bank set `game_id`=%u, `gz_id`=%u where `bank_id` = %u and `type` = 1", bank.game_id, bank.gz_id, bank.bank_id);
}

//-----------------------------------------------------------------------
bool 	CenterBankManager::InputBankBuffer(CharPtr & pChr, const uint32 & thegid, GameBank & bank, const uint8 & status, const bool & safe /* = false */)
{
	if(pChr.isNull())
		return false;
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator iter, enditer = items.end();
	for (iter = items.begin(); iter != enditer; ++ iter)
	{
		ItemPtr pItem = *iter;		
		uint32 modelId = pItem->getUInt32Field("model_id");
		uint32 currNum = pItem->getUInt32Field("num");
		// Log.Debug("CenterBankManager::InputBankBuffer 111","char[%u] modelId[%u] currNum[%u]", pChr->getHandle(), modelId, currNum);
		if (GetFieldName(thegid, modelId) == NULL)
			continue;
		// Log.Debug("CenterBankManager::InputBankBuffer 222","char[%u] modelId[%u] currNum[%u]", pChr->getHandle(), modelId, currNum);
		
		pItem->setUInt32Field("num", 0);
		pItem->SaveDB();
		SetBankSafeItemNum(bank, modelId, currNum);
	}
	
	XMLDataSet vipXml;
	if(sVipCardMgr.GetVipXmlData(pChr, vipXml))
	{// VIP相关数据
		bank.user_data = vipXml.getXML();		
	}
	if (pChr->getUInt32Field("id")){
		bank.data5 = pChr->getUInt32Field("id");
	}
	bank.status = BankStatusPrep;	
	bank.gz_id = 0;
	bank.src_gz_id = pChr->getUInt32Field("gz_id");
	
	// 2018-07-21 带一些游戏角色相关的数据过去 用 type = 1 的bank sdata1字段
	Json::Value val;
	val["lv"] = pChr->getUInt32Field("lv");
	val["exps"] = pChr->getUInt32Field("exps");
	
	Json::FastWriter w;
	bank.sdata4 = w.write(val);
	
	// 更新银行
	UpdateBankBuffDB(bank, status);	
	return true;
}

//-----------------------------------------------------------------------
bool 	CenterBankManager::OutputBankBuffer(CharPtr & pChr,const uint32 & theserverid,  GameBank & bank, const uint8 & status, const bool & safe /* = false */)
{
	if(pChr.isNull())
		return false;
	GameBank tmpBank = bank;
	// Log.Error("CenterBankManager", "111OutputBankBuffer bank.data1[%u]", bank.data1);
	if (bank.data5)
		pChr->setUInt32Field("id", bank.data5);	
	bank.status = BankStatusFree;	
	bank.user_data = "";
	bank.gz_id = pChr->getUInt32Field("gz_id");
	bank.data1 = 0;
	bank.data2 = 0;
	bank.data3 = 0;
	bank.data4 = 0;
	bank.data5 = 0;
	bank.item1 = 0;
	bank.item2 = 0;
	bank.item3 = 0;
	bank.item4 = 0;
	bank.item8 = 0;
	bank.item9 = 0;
	bank.item10 = 0;
	bank.item11 = 0;
	bank.item12 = 0;
	bank.item13 = 0;
	bank.item14 = 0;
	bank.item15 = 0;
	bank.item17 = 0;
	bank.item18 = 0;
	bank.item19 = 0;
	bank.item20 = 0;
	
	// 拷贝带过来的一些游戏角色相关数据
	Json::Value val;
	Json::Reader reader;
	reader.parse(bank.sdata4, val);
	
	if(val.isMember("lv"))		// 抄写带过来的等级
		pChr->setUInt32Field("lv", val["lv"].asUInt());
	
	if(val.isMember("exps"))	// 抄写带过来的经验值
		pChr->setUInt32Field("exps", val["exps"].asUInt());
	
	bank.sdata4 = "";
	
	// 先把银行数据清空
	UpdateBankBuffDB(bank, status);
	
	std::map<uint32, uint32> mapItems;
	uint32 modelid = 0;
	modelid = en_ItemModelId_Coins;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Match;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Exchange;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_RRQ;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Gold;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Bugle;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Mammon;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Mammon2;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Diamond;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Diamond2;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Luck;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Luck2;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Luck3;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Subsidy;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Token;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Score;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_BuQianKa;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_GoldTicket;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_DiamondOpen;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = ItemModel_LingGouBi;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	modelid = en_ItemModelId_Money;
	mapItems.insert(std::make_pair(modelid, GetBankSafeItemNum(tmpBank, modelid)));
	
	std::map<uint32, uint32>::iterator iter, enditer = mapItems.end();
	for (iter = mapItems.begin(); iter != enditer; ++ iter)
	{
		uint32 modelid = iter->first;
		uint32 num = iter->second;
		// uint32 currnum = 0;
		// GetItemNum(pChr, modelid, &currnum);		
		// Log.Error("CenterBankManager", "111OutputBankBuffer pChr[%u] pRep[x%08x] modelid[%u] num[%u]", pChr->getHandle(), pChr.get(), modelid, num);
		addItemNum(theserverid, pChr, modelid, num);
		// GetItemNum(pChr, modelid, &currnum);
		// Log.Error("CenterBankManager", "222OutputBankBuffer pChr[%u] pRep[x%08x] modelid[%u] num[%u]", pChr->getHandle(), pChr.get(), modelid, currnum);
	}	
	XMLDataSet vipXml;
	vipXml.Load(tmpBank.user_data);
	sVipCardMgr.SetVipXmlData(pChr, vipXml);
	pChr->SaveDB();	
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateOpServerResult(WorldPacket * packet,const uint8 & type, const uint8 & result, const uint16 & gameid)
{
	if(!packet)
		return false;	
	packet->clear();
	packet->SetOpcode(SMSG_LINKGAMESERVER);
	*packet << uint16(SMSG_LINKGAMESERVER) << uint16(0);
	*packet << type << result << gameid;
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateExitGameResult(WorldPacket *packet, uint8 result, uint32 gzid)
{
	if(!packet)
		return false;	
	packet->clear();
	packet->SetOpcode(SMSG_EXITGAMESERVER);
	*packet << uint16(SMSG_EXITGAMESERVER) << uint16(0);
	*packet << result << gzid;
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateExitGameResultEx(WorldPacket *packet, uint8 result, uint32 gzid)
{
	if(!packet)
		return false;	
	packet->clear();
	packet->SetOpcode(SMSG_EXITGAMESERVEREX);
	*packet << uint16(SMSG_EXITGAMESERVEREX) << uint16(0);
	*packet << result << gzid;
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::SetSafeItemFlag(CharPtr & pChr, const uint32 & modelid)
{
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid)
		{
			uint32 num = (*ii)->getUInt32Field("num");
			(*ii)->setUInt32Field("flag", BankItemPrep);
			(*ii)->setUInt32Field("attribute_ext", (*ii)->getUInt32Field("attribute_ext") + num);
			(*ii)->setUInt32Field("num", 0);
			(*ii)->SaveDB();
			return true;
		}
	}
	
	return false;
}
//-------------------------------------------------------------------
void 	CenterBankManager::SetBankDataFlag(CharPtr & pChr)
{
	SetSafeItemFlag(pChr, en_ItemModelId_Coins);
	SetSafeItemFlag(pChr, en_ItemModelId_Exchange);
	SetSafeItemFlag(pChr, en_ItemModelId_Gold);
	SetSafeItemFlag(pChr, en_ItemModelId_Match);
	SetSafeItemFlag(pChr, en_ItemModelId_Bugle);
	SetSafeItemFlag(pChr, en_ItemModelId_Mammon);
	SetSafeItemFlag(pChr, en_ItemModelId_Mammon2);
	SetSafeItemFlag(pChr, en_ItemModelId_Diamond);
	SetSafeItemFlag(pChr, en_ItemModelId_Diamond2);
	SetSafeItemFlag(pChr, en_ItemModelId_Money);
	SetSafeItemFlag(pChr, en_ItemModelId_Luck);
	SetSafeItemFlag(pChr, en_ItemModelId_Luck2);
	SetSafeItemFlag(pChr, en_ItemModelId_Luck3);
	SetSafeItemFlag(pChr, en_ItemModelId_Subsidy);
	SetSafeItemFlag(pChr, en_ItemModelId_Token);
	SetSafeItemFlag(pChr, en_ItemModelId_Score);
	SetSafeItemFlag(pChr, en_ItemModelId_BuQianKa);
	SetSafeItemFlag(pChr, en_ItemModelId_GoldTicket);
	SetSafeItemFlag(pChr, en_ItemModelId_DiamondOpen);
	SetSafeItemFlag(pChr, ItemModel_LingGouBi);
}
//-------------------------------------------------------------------
bool 	CenterBankManager::resetSafeItemNum(const uint16 & thegid, CharPtr & pChr, const uint32 & modelid, const uint32 & num)
{
	if(pChr.isNull() || modelid == 0)
		return false;
	const String *field = GetFieldName(thegid, modelid);
	if (field == NULL)
		return false;
	
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid)
		{
			(*ii)->setUInt32Field("flag", BankItemFree);
			(*ii)->setUInt32Field("num", num);	
			(*ii)->setUInt32Field("attribute_ext", 0);			
			if(*field != "")
				pChr->setUInt32Field(*field, num);	
			(*ii)->SaveDB();
			return true;
		}
	}
	
	return false;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::restoreSafeItemNum(const uint16 & thegid, CharPtr & pChr, const uint32 & modelid)
{
	if(pChr.isNull() || modelid == 0)
		return false;
	const String *field = GetFieldName(thegid, modelid);
	if (field == NULL)
		return false;
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == modelid && (*ii)->getUInt32Field("flag") == BankItemPrep)
		{
			uint32 num = (*ii)->getUInt32Field("attribute_ext") + (*ii)->getUInt32Field("num");
			(*ii)->setUInt32Field("flag", BankItemFree);
			(*ii)->setUInt32Field("num", num);	
			(*ii)->setUInt32Field("attribute_ext", 0);
			if(*field != "")
				pChr->setUInt32Field(*field, num);	
			(*ii)->SaveDB();
			return true;
		}
	}
	
	return false;
}
//-------------------------------------------------------------------
void 	CenterBankManager::restoreDataFlag(const uint16 & thegid, CharPtr & pChr)
{	
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Coins);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Exchange);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Gold);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Match);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Bugle);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Mammon);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Mammon2);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Diamond);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Diamond2);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Money);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Luck);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Luck2);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Luck3);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Subsidy);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Token);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_Score);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_BuQianKa);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_GoldTicket);
	restoreSafeItemNum(thegid, pChr, en_ItemModelId_DiamondOpen);
	restoreSafeItemNum(thegid, pChr, ItemModel_LingGouBi);
}
//-------------------------------------------------------------------
void 	CenterBankManager::ResetGameExchage(UserPtr & pUser)
{
	if(pUser.isNull())
		return;
		
	/*CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return;
	
	GameBank bank;
	std::list<GameBank> lstBankInfo;
	sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE);
	if(lstBankInfo.empty())
		return;
		
	uint32 gid = pUser->getUInt32Field("gz_id");
	bank = lstBankInfo.front();
	if(bank.status == BankStatusFree || bank.status == BankStatusLogouted)
	{
		pChr->setUInt32Field("ishere", gid);
		pChr->SaveDB();
		return;
	}
	
	 if(bank.status == BankStatusLogined || bank.status == BankStatusLogouting)
	{// 数据在子游戏里面
		InputBankBuffer(pChr, gid, bank, BankStatusLogouted, true);		
	}
	else
	{// 数据在银行里面
		bank.status = BankStatusLogouted;
		updateBankStatusDB(bank, BankStatusLogouted, BankStatusPrep);
	} 
	
	WSSocketPtr pSocket = pChr->getSocket();
	if(!pSocket.isNull())
	{
		pSocket->Disconnect();
	}*/
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateItem(CharPtr & container, const uint32 & model_id, const uint32 & num)
{
	ItemPtr item;
	if(container.isNull() || model_id == 0)
		return false;
	
	const String *pStr = GetFieldName(container->getUInt32Field("gz_id"), model_id);
	if (pStr == NULL)
		return false;
	
	ItemModelPtr imp = sItemModelMgr.load(model_id);
	if(imp.isNull())
		return false;
	
	std::list<ItemPtr> items;
	container->getItemsList(&items);	
	std::list<ItemPtr>::iterator iter,ei = items.end();
	for(iter = items.begin(); iter!=ei; ++iter)
	{
		if((*iter)->model->getHandle() == model_id)
			return false;
	}	
	
	Resource * pItem = sItemMgr.newDumyItem(model_id);
	pItem->setUInt32Field("status", Item::ItemStatusNormal);
	pItem->setUInt32Field("model_id", model_id);
	pItem->setStringField("name", imp->getStringField("name"));
	pItem->setUInt32Field("container", container->getHandle());
	pItem->setUInt32Field("container_type", container->getTargetType());
	pItem->setUInt32Field("num", num);
	
	item = sItemMgr.createItemDatabase(pItem);
	sItemMgr.freeDumyItem(pItem);
	item->load();
	return true;
}

//-------------------------------------------------------------------
void	CenterBankManager::GetPublicData(UserPtr &pUser, GameBank *pBank)
{
	if (pUser.isNull() || pBank == NULL)
		return;
	std::list<GameBank> lstBanks;
	if (!sChannelMgr.getBankList(&lstBanks, 0, 1, "`platform_id`=%u AND `type`=%u", pUser->getUInt32Field("platform_id"), PUBLIC_TYPE))
	{
		// 创建
		uint64 bankid = 0;
		GameBank *pGameBank = sChannelMgr.newDumyBank();
		if (pGameBank)
		{
			pGameBank->platform_id = pUser->getUInt32Field("platform_id");
			pGameBank->game_id = pUser->getUInt32Field("gz_id");
			pGameBank->type = PUBLIC_TYPE;
			pGameBank->status = BankStatusFree;
			pGameBank->uid = pUser->getHandle();
			pGameBank->name = pUser->getStringField("name");
			pGameBank->nick = pUser->getStringField("nick");	
			bankid = sChannelMgr.addBankDB(pGameBank);
			if(pBank != NULL)
			{
				*pBank = *pGameBank;
				pBank->bank_id = bankid;
			}
		}
		sChannelMgr.freeDumyBank(pGameBank);
	}
	else
		*pBank = lstBanks.front();
}

//-------------------------------------------------------------------
bool	CenterBankManager::GetPublicData(const uint32 &platform_id, GameBank *pBank)
{
	std::list<GameBank> lstBanks;
	if (!sChannelMgr.getBankList(&lstBanks, 0, 1, "`platform_id`=%u AND `type`=%u", platform_id, PUBLIC_TYPE)){
		return false;
	}
	else
		*pBank = lstBanks.front();
	return true;
}

// 设置公共配置
void 	CenterBankManager::SetPublicConfig(UserPtr &pUser, String strConfig)
{
	GameBank pubData;
	GetPublicData(pUser, &pubData);
	
	pubData.sdata4 = strConfig;
	sChannelMgr.updateBankDB(&pubData);
}

//-------------------------------------------------------------------
uint32 CenterBankManager::AddPublicData(UserPtr &pUser, const uint32 &pd_type, const uint32 &number, const uint32  &source)
{
	if (pUser.isNull() || !pUser->getUInt32Field("platform_id"))
		return 0;
	GameBank pBank;
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), PUBLIC_TYPE))
	{
		// 创建
		uint64 bankid = 0;
		GameBank *pGameBank = sChannelMgr.newDumyBank();
		if (pGameBank)
		{
			pGameBank->platform_id = pUser->getUInt32Field("platform_id");
			pGameBank->game_id = pUser->getUInt32Field("gz_id");
			pGameBank->type = PUBLIC_TYPE;
			pGameBank->status = BankStatusFree;
			pGameBank->uid = pUser->getHandle();
			pGameBank->name = pUser->getStringField("name");
			pGameBank->nick = pUser->getStringField("nick");			
			bankid = sChannelMgr.addBankDB(pGameBank);
			if(pGameBank != NULL)
			{
				*pGameBank = *pGameBank;
				pGameBank->bank_id = bankid;
				pBank = *pGameBank;
			}
		}
		sChannelMgr.freeDumyBank(pGameBank);
	}
	else
		pBank = lstBankInfo.front();
	
	String field = "";
	uint32 tempNumber = 0;
	switch (pd_type)
	{
		case en_PublicData_Silver:
			{
				field = "data1";
				tempNumber = (pBank.data1 += number);
				break;
			}
		case en_PublicData_Gold:
			{
				field = "data2";
				tempNumber = (pBank.data2 += number);
				break;
			}
		case en_PublicData_FirstBuy:
			{
				field = "data3";
				tempNumber = (pBank.data3 += number);
				break;
			}
		case en_PublicData_FirstBuyTimer:
			{
				field = "data4";
				tempNumber = (pBank.data4 += number);
				break;
			}
		case en_PublicData_GetLemaTime:
			{
				field = "data5";
				tempNumber = (pBank.data5 += number);
				break;
			}
		default:
			return 0;
	}
	updatePublicDataDB(pBank.bank_id, field, tempNumber);
	updatePublicDataLog(pUser, en_UNT_Add, pd_type, number, source);
	return tempNumber;
}
//-------------------------------------------------------------------
bool CenterBankManager::ReducePublicData(UserPtr &pUser, const uint32 &pd_type, const uint32 &number, const uint32  &source)
{
	if (pUser.isNull() || 0 == pUser->getUInt32Field("platform_id"))
		return false;
	
	GameBank pBank;
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), PUBLIC_TYPE))
	{
		// 创建
		uint64 bankid = 0;
		GameBank *pGameBank = sChannelMgr.newDumyBank();
		if (pGameBank)
		{
			pGameBank->platform_id = pUser->getUInt32Field("platform_id");
			pGameBank->game_id = pUser->getUInt32Field("gz_id");
			pGameBank->type = PUBLIC_TYPE;
			pGameBank->status = BankStatusFree;
			pGameBank->uid = pUser->getHandle();
			pGameBank->name = pUser->getStringField("name");
			pGameBank->nick = pUser->getStringField("nick");			
			bankid = sChannelMgr.addBankDB(pGameBank);
			if(pGameBank != NULL)
			{
				*pGameBank = *pGameBank;
				pGameBank->bank_id = bankid;
				pBank = *pGameBank;
			}
		}
		sChannelMgr.freeDumyBank(pGameBank);
	}
	else
		pBank = lstBankInfo.front();
	
	String field = "";
	uint32 tempNumber = 0;
	switch (pd_type)
	{
		case en_PublicData_Silver:
			{
				if (pBank.data1 < number)
					return false;
				field = "data1";
				tempNumber = (pBank.data1 -= number);
				break;
			}
		case en_PublicData_Gold:
			{
				if (pBank.data2 < number)
					return false;
				field = "data2";
				tempNumber = (pBank.data2 -= number);
				break;
			}
		case en_PublicData_FirstBuy:
			{
				if (pBank.data3 < number)
					return false;
				field = "data3";
				tempNumber = (pBank.data3 -= number);
				break;
			}
		case en_PublicData_FirstBuyTimer:
			{
				if (pBank.data4 < number)
					return false;
				field = "data4";
				tempNumber = (pBank.data4 -= number);
				break;
			}
		case en_PublicData_GetLemaTime:
			{
				if (pBank.data5 < int(number))
					return false;
				field = "data5";
				tempNumber = (pBank.data5 -= int(number));
				break;
			}
		default:
			return 0;
	}
	updatePublicDataDB(pBank.bank_id, field, tempNumber);
	updatePublicDataLog(pUser, en_UNT_Reduce, pd_type, number, tempNumber, source);
	return true;
}

//-------------------------------------------------------------------
void CenterBankManager::SetPublicData(UserPtr &pUser, const uint32 &pd_type, const uint32 &number)
{
	if (pUser.isNull() || 0 == pUser->getUInt32Field("platform_id"))
		return ;
	
	GameBank pBank;
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), PUBLIC_TYPE))
	{
		// 创建
		uint64 bankid = 0;
		GameBank *pGameBank = sChannelMgr.newDumyBank();
		if (pGameBank)
		{
			pGameBank->platform_id = pUser->getUInt32Field("platform_id");
			pGameBank->game_id = pUser->getUInt32Field("gz_id");
			pGameBank->type = PUBLIC_TYPE;
			pGameBank->status = BankStatusFree;
			pGameBank->uid = pUser->getHandle();
			pGameBank->name = pUser->getStringField("name");
			pGameBank->nick = pUser->getStringField("nick");			
			bankid = sChannelMgr.addBankDB(pGameBank);
			if(pGameBank != NULL)
			{
				*pGameBank = *pGameBank;
				pGameBank->bank_id = bankid;
				pBank = *pGameBank;
			}
		}
		sChannelMgr.freeDumyBank(pGameBank);
	}
	else
		pBank = lstBankInfo.front();
	
	String field = "";
	uint32 tempNumber = number;
	switch (pd_type)
	{
		case en_PublicData_Silver:
			{
				field = "data1";
				break;
			}
		case en_PublicData_Gold:
			{
				field = "data2";
				break;
			}
		case en_PublicData_FirstBuy:
			{
				field = "data3";
				break;
			}
		case en_PublicData_FirstBuyTimer:
			{
				field = "data4";
				break;
			}
		case en_PublicData_GetLemaTime:
			{
				field = "data5";
				break;
			}
		default:
			return;
	}
	updatePublicDataDB(pBank.bank_id, field, tempNumber);
	updatePublicDataLog(pUser, en_UNT_Reduce, pd_type, number, tempNumber);
	return ;
}
//-------------------------------------------------------------------
uint32 CenterBankManager::GetPublicData(UserPtr &pUser, const uint32 &pd_type)
{
	if (pUser.isNull())
		return 0;
	
	GameBank pBank;
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), PUBLIC_TYPE))
		return 0;
		
	pBank = lstBankInfo.front();	
	switch (pd_type)
	{
		case en_PublicData_Silver:
			return pBank.data1;
		case en_PublicData_Gold:
			return pBank.data2;
		case en_PublicData_FirstBuy:
			return pBank.data3;
		case en_PublicData_FirstBuyTimer:
			return pBank.data4;
		case en_PublicData_GetLemaTime:
			return pBank.data5;
		default:
			break;
	}
	return 0;
}
//-------------------------------------------------------------------
bool CenterBankManager::GetPublicData(UserPtr &pUser, BankPublicData *st)
{
	if (pUser.isNull() || st == NULL)
		return false;
	
	GameBank pBank;
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), PUBLIC_TYPE))
		return false;
	pBank = lstBankInfo.front();
	st->Silver = pBank.data1;
	st->Gold = pBank.data2;
	st->FirstBuy = pBank.data3;
	st->FirstBuyTimer = pBank.data4;
	st->GetLemaTime = pBank.data5;
	return true;
}
//-------------------------------------------------------------------
bool CenterBankManager::updatePublicDataDB(const uint32 &bankid, const String &field, const uint32 &number)
{
	return CenterDatabase.WaitExecute("update game_bank set `%s`=%u, `last_time`=%u where `bank_id`=%u", field.c_str(), number, time(0), bankid);
}
//-------------------------------------------------------------------
void CenterBankManager::updatePublicDataLog(UserPtr &pUser, const uint32 &operate, const uint32 &pd_type, 
					const uint32 &upNum, const uint32 &currNum, const uint32  &source)
{
	if(pUser.isNull() || !source)
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	pLog->status = 1;
	pLog->type = en_Operate_PublicItem;
	pLog->src_id= pUser->getUInt32Field("platform_id");
	pLog->dest_type = operate;	
	pLog->data1 = pd_type;
	pLog->data2 = upNum;
	pLog->data3 = currNum;
	char strDesc[256] = "";
	sprintf(strDesc, "PID为【%u】的玩家在【%u】分区，因【%s】，【%s数量%u】，类型为【%u】的公共数据，剩余【%u】", 
		pLog->src_id, pUser->getUInt32Field("gz_id"), sLogDataMgr.GetLogCause(source).c_str(), 
		(operate == en_UNT_Add ? "增加" : "减少"), upNum, pd_type, currNum);	
	String szDesc = strDesc;
	pLog->info = GetUTF8String(szDesc);
	pLog->create_time = sTools.GetCurDateTime();
	sChannelMgr.addCenterLogDB(pLog);
	sChannelMgr.freeDumyCenterLog(pLog);
}
//-------------------------------------------------------------------
void CenterBankManager::LeMaOpLog(const uint32 & pid,const uint8 & mode,const uint32 & exchange_id,const uint32 & data1)
{
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return;
	}
	
	pLog->status = 1;
	pLog->type = LEMA_LOG_TYPE;
	pLog->src_id= pid;
	pLog->sub_type = mode;
	pLog->dest_id = exchange_id;
	pLog->data1	= data1;
	
	pLog->create_time = sTools.GetCurDateTime();
	sChannelMgr.addCenterLogDB(pLog);
	sChannelMgr.freeDumyCenterLog(pLog);
	return ;
}

//-----------------------------------------------------------------------
void CenterBankManager::UpdateFarmInfoLog(CharPtr & pChr,const uint8 & sub_type,const uint8 & op_type, 
										const uint32 & model_id,const uint8 & num,
										std::map<uint32,uint32> mapFarms,const uint32 & destPId)
{
	if(pChr.isNull())
		return ;
	
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if (NULL == pLog ||pChr.isNull())
	{
		sChannelMgr.freeDumyCenterLog(pLog);
		return;
	}
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return;
	
	// 填充日志信息
	pLog->server_id = sChannelMgr.getServerID();
	pLog->status = 1;
	
	// 日志类型
	pLog->type = en_GLT_Farm;
	pLog->sub_type = sub_type;
	
	// 日志所属玩家PID
	pLog->src_id = pUser->getUInt32Field("platform_id");
	// 目标对象玩家PID
	pLog->dest_id = destPId;
	// 操作动物模式ID
	pLog->target_id = model_id;
	
	// 牧场动物模式ID
	pLog->data1 = num;
	// 增减（1：增 2：减）
	pLog->data2 = op_type;
	
	pLog->platform_id = pUser->getUInt32Field("platform_id");
	pLog->user_name = pUser->getStringField("name");
	pLog->user_nick = pUser->getStringField("nick");
	pLog->user_ip = pUser->getStringField("ip");
	pLog->user_addr = pUser->getStringField("addr");
	pLog->user_id = pUser->getUInt32Field("reg_from");
	pLog->char_id = pUser->getUInt32Field("char_id");
	pLog->flag = pUser->getUInt32Field("status");
	
	std::map<uint32,uint32>::iterator iter,ei = mapFarms.end();
	for(iter = mapFarms.begin(); iter!=ei; ++iter)
	{
		uint32 num = iter->second;
		switch(iter->first)
		{
		case 2:
			pLog->data3 = num;
			break;
		case 3:
			pLog->data4 = num;
			break;
		case 4:
			pLog->data5 = num;
			break;
		case 5:
			pLog->data6 = num;
			break;
		case 6:
			pLog->data7 = num;
			break;
		case 7:
			pLog->data8 = num;
			break;
		case 8:
			pLog->data9 = num; 
		default:
			break;
		}
	}
	
	//字符串记录日志详情
	
	
	pLog->create_time = sGLMgr.GetCurDateTime();
	sChannelMgr.addCenterLogDB(pLog);
	sChannelMgr.freeDumyCenterLog(pLog);
}

// 更新宠物库存数量
void CenterBankManager::UpdateFarmNumber(CharPtr & pChr,std::map<uint32,uint32> mapFarms)
{
	if(pChr.isNull())
		return ;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	// type类型为2的银行数据
	GameBank bank;
	GetPublicData(pUser, &bank);
	
	if(bank.bank_id == 0)
		return ;
	
	uint32 total_farmCoins = 0;
	
	std::map<uint32,uint32>::iterator iter,ei = mapFarms.end();
	for(iter = mapFarms.begin(); iter!=ei; ++iter)
	{
		switch(iter->first)
		{
		case 2:
			{
				bank.item1 = iter->second;
				total_farmCoins += bank.item1 * 150000;
			}
			break;
		case 3:
			{
				bank.item2 = iter->second;
				total_farmCoins += bank.item2 * 200000;
			}
			break;
		case 4:
			{
				bank.item3 = iter->second;
				total_farmCoins += bank.item3 * 500000;
			}
			break;
		case 5:
			{
				bank.item4 = iter->second;
				total_farmCoins += bank.item4 * 1000000;
			}
			break;
		case 6:
			{
				bank.item5 = iter->second;
				total_farmCoins += bank.item5 * 2000000;
			}
			break;
		case 7:
			{
				bank.item6 = iter->second;
				total_farmCoins += bank.item6 * 5000000;
			}
			break;
		case 8:
			{
				bank.item7 = iter->second;
				total_farmCoins += bank.item7 * 10000000;
			}
			break;
		}
	}
	
	sChannelMgr.updateBankDB(&bank);
}

//-------------------------------------------------------------------
bool CenterBankManager::isChangeTestUser(CharPtr &pChr)
{
	if (pChr.isNull())
		return false;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull() || !sXmlDataMgr.GetConfXMLValue("OPEN_CHANGE_DEBUG_MODE"))
		return false;
	uint32 pid = pUser->getUInt32Field("platform_id");
	return (pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST1") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST2") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST3") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST4") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST5") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST6") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST7") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST8") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST9") ||
		pid == sXmlDataMgr.GetConfXMLValue("CHANGE_DEBUG_TEST10"));		
}
//-------------------------------------------------------------------
uint32  CenterBankManager::GetGameGZID(UserPtr &pUser)
{
	if (pUser.isNull())
		return 0;
	GameBank pBank;
	std::list<GameBank> lstBankInfo;
	if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u AND `type` = %u", pUser->getUInt32Field("platform_id"), GAME_TYPE))
		return 0;
	pBank = lstBankInfo.front();
	return pBank.game_id;
}

// 银行自动取款
void CenterBankManager::GetUserBankCoinsBySystem(UserPtr & pUser)
{
	if(pUser.isNull())
		return ;
	
	// 趣玩的银行功能继续使用
	if(pUser->getUInt32Field("reg_from") == 5011)
		return ;
	
	GameBank realBank;
	if(sBankMgr.GetRealBank(pUser, realBank))
	{// 有存款的玩家以邮件附件的形式把钱给玩家取出来
		uint32 bank_coins = realBank.coins;
		if(bank_coins)
		{
			realBank.coins = 0;
			sChannelMgr.updateBankDB(&realBank);
			
			uint32 pid = pUser->getUInt32Field("platform_id");
			
			std::map<uint32,uint32> mapItems;
			mapItems.insert(std::make_pair(ItemModel_Coins, bank_coins));
			
			String szTitle = "";
			String szContent = "";
			
			const MailModel * mailM = sXmlDataMgr.GetMailModel("STSTEM_GETBANKCOINS");
			if(mailM)
			{
				szTitle = mailM->szTitle;
				szContent = mailM->szContent;
				
				char buf[256] = "";
				// 亲爱的玩家：由于银行功能改版，现将您原有银行存款【%u】铜钱为您取出，请您收取！
				sprintf(buf, szContent.c_str(), bank_coins);
				
				szContent = buf;
			}
			
			sGLMgr.CreateMail(pid, szTitle, szContent, 0, en_ST_SystemGetBankCoins, &mapItems);
		}
	}
}
	
//-------------------------------------------------------------------
bool 	CenterBankManager::GetOrSignin(UserPtr &pUser, const uint32 &opType, const uint32 &data1)
{
	if (pUser.isNull())
		return false;
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if (pChr.isNull())
		return false;
	WSSocketPtr pSocket = pChr->getSocket();
	if (pSocket.isNull())
		return false;
	uint32 viploginBonus = 0;
	time_t nt = time(0);
	tm ttm = *localtime(&nt);
	GameBank bank;
	GetPublicData(pUser, &bank);
	String strJson = bank.sdata1;
	SigninStruct ss;
	SigninOfJsonToStruct(strJson, &ss);	
	uint32 jlNum = 0;
	bool newBonus = false;
	if (opType == 1)
	{// 领取连续签到奖励		
		switch(data1)
		{
			case 1:
				if (ss.day5 == 1)
				{
					ss.day5 = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("5DAY_SIGN_BONUS");
				}
				break;
			case 2:
				if (ss.day10 == 1)
				{
					ss.day10 = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("10DAY_SIGN_BONUS");
				}
				break;
			case 3:
				if (ss.day15 == 1)
				{
					ss.day15 = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("15DAY_SIGN_BONUS");
				}
				break;
			case 4:
				if (ss.day20 == 1)
				{
					ss.day20 = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("20DAY_SIGN_BONUS");
				}
				break;
			case 5:
				if (ss.dayAll == 1)
				{
					ss.dayAll = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("ALLDAY_SIGN_BONUS");
				}
				break;
			default:
				return false;
		}
		if (jlNum == 0)
			return false;		
	}
	else if (opType == 2)
	{// 累计签到		
		switch(data1)
		{
			case 1:
				if (ss.total5 == 1)
				{
					ss.total5 = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("TOTAL_5DAY_SIGN_BONUS");
				}
				break;
			case 2:
				if (ss.total15 == 1)
				{
					ss.total15 = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("TOTAL_15DAY_SIGN_BONUS");
				}
				break;
			case 3:
				if (ss.total25 == 1)
				{
					ss.total25 = 2;
					jlNum = sXmlDataMgr.GetConfXMLValue("TOTAL_25DAY_SIGN_BONUS");
				}
				break;
			default:
				return false;
		}
		if (jlNum == 0)
			return false;
	}
	else
	{// 日签
		if (ss.month != (uint32)ttm.tm_mon)
		{// 不是同月
			ss.Init();
			ss.month = ttm.tm_mon;
		}
		if (data1 == 0)
		{// 当日签到			
			std::map<uint32, bool>::iterator iter = ss.mapDays.find(ttm.tm_mday);
			if (iter != ss.mapDays.end() && iter->second){// 已签到	
				return false;
			}
			// viploginBonus = sVipCardMgr.GetVIPLoginCoins(pChr);
			sVipCardMgr.AddLoginGift(pChr, viploginBonus);
			ss.mapDays[ttm.tm_mday] = true;			
			// 发放签到奖励
			jlNum = sXmlDataMgr.GetConfXMLValue("1DAY_SIGN_BONUS");
		}
		else
		{// 补签			
			std::map<uint32, bool>::iterator iter = ss.mapDays.find(data1);
			if (iter != ss.mapDays.end() && iter->second){// 已签到
				Log.Error("CenterBankManager Test", "/////////GetOrSignin pChr[%u] data1[%u] BuQianed!", pChr->getHandle(), data1);
				return false;
			}
			if (!sGLMgr.reduceItemNum(pChr, ItemModel_BuQianKa, 1))
			{
				Log.Error("CenterBankManager Test", "/////////GetOrSignin pChr[%u] no BuQianKa!", pChr->getHandle());
				return false;
			}
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_BuQianKa, en_UNT_Reduce, 1, en_HSI_Login, opType, data1);
			// 发放签到奖励
			ss.mapDays[data1] = true;
			jlNum = sXmlDataMgr.GetConfXMLValue("1DAY_SIGN_BONUS");
		}
		// 判断连续签到
		std::set<uint32> setCounts;
		uint32 count = 1;
		std::map<uint32, bool>::iterator mapi, endmapi = ss.mapDays.end();
		for (mapi = ss.mapDays.begin(); mapi != endmapi; ++ mapi)
		{			
			std::map<uint32, bool>::iterator iter = ss.mapDays.find(mapi->first+1);
			if (iter != ss.mapDays.end() && iter->second){
				++ count;
				if (count >= 5 && ss.day5 == 0)
				{
					ss.day5 = 1;
					newBonus = true;				
				}
				if (count >= 10 && ss.day10 == 0)
				{
					ss.day10 = 1;
					newBonus = true;
				}
				if (count >= 15 && ss.day15 == 0)
				{
					ss.day15 = 1;
					newBonus = true;
				}
				if (count >= 20 && ss.day20 == 0)
				{
					ss.day20 = 1;
					newBonus = true;
				}
			}
			else
			{
				setCounts.insert(count);
				count = 1;
			}
		}
		
		bool bRunYear = false;
		if((ttm.tm_year % 4 == 0 && ttm.tm_year % 100 != 0) || ttm.tm_year % 400 == 0)
			bRunYear = true;
		
		Log.Debug("CenterBankManager::GetOrSignin","bRunYear[%u] tm_year[%u]", bRunYear, ttm.tm_year);
		
		// 得到当月最大值
		uint32 allCount = 0;
		switch(ttm.tm_mon)
		{
			case 1:
			{
				if(bRunYear)
					allCount = 29;
				else
					allCount = 28;
				break;
			}
			case 3:
			case 5:
			case 8:
			case 10:
			{
				allCount = 30;
				break;
			}			
			default:
			{
				allCount = 31;
				break;
			}
		}
		
		Log.Debug("CenterBankManager::GetOrSignin","allCount[%u]", allCount);
		if (ss.mapDays.size() >= allCount)
		{// 全勤
			if (ss.dayAll == 0){
				ss.dayAll = 1;
				newBonus = true;
			}
		}
		if (ss.mapDays.size() >= 25)
		{
			if (ss.total25 == 0){
				ss.total25 = 1;
				newBonus = true;
			}
		}
		if (ss.mapDays.size() >= 15)
		{
			if (ss.total15 == 0){
				ss.total15 = 1;
				newBonus = true;
			}
		}
		if (ss.mapDays.size() >= 5)
		{
			if (ss.total5 == 0){
				ss.total5 = 1;
				newBonus = true;
			}
		}
	}
	// 给予奖励
	jlNum += viploginBonus;
	sGLMgr.addItemNum(pChr, ItemModel_Coins, jlNum);
	sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_Coins, en_UNT_Add, jlNum, en_HSI_Login, opType, data1);
	WorldPacket packet;
	if (CreateSigninResultPacket(&packet, opType, data1, jlNum))
		pSocket->SendPacket(&packet);
	if (newBonus && CreateSigninInfoPacket(&packet, pUser, ss, viploginBonus))
		pSocket->SendPacket(&packet);	
	// 回写数据库
	strJson = SigninOfStructToJson(ss);
	CenterDatabase.WaitExecute("update game_bank set `sdata1`='%s' where `bank_id` = %u", strJson.c_str(), bank.bank_id);	
	// Log.Error("CenterBankManager Test", "///////jlNum[%u]\nstrJson[%s]", jlNum, strJson.c_str());
	
	return true;
}
//-------------------------------------------------------------------
String CenterBankManager::SigninOfStructToJson(SigninStruct &ss)
{
	Json::Value child;
	child["month"] = Json::Value((uint32)ss.month);
	Json::Value days;
	std::map<uint32, bool>::iterator iter, enditer = ss.mapDays.end();
	for (iter = ss.mapDays.begin(); iter != enditer; ++ iter)
	{
		Json::Value day;
		day["day"] = Json::Value((uint32)iter->first);
		day["sign"] = Json::Value((uint32)iter->second);
		days.append(day);
	}
	child["days"] = days;
	child["day5"] = Json::Value((uint32)ss.day5);
	child["day10"] = Json::Value((uint32)ss.day10);
	child["day15"] = Json::Value((uint32)ss.day15);
	child["day20"] = Json::Value((uint32)ss.day20);
	child["dayAll"] = Json::Value((uint32)ss.dayAll);
	
	child["total5"] = Json::Value((uint32)ss.total5);
	child["total15"] = Json::Value((uint32)ss.total15);
	child["total25"] = Json::Value((uint32)ss.total25);
	Json::StyledWriter styWriter;
	return styWriter.write(child);
}
//-------------------------------------------------------------------
bool CenterBankManager::SigninOfJsonToStruct(const String &strJson, SigninStruct *pSign)
{
	if (strJson == "")
	{
		pSign->Init();
		return false;
	}
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	pSign->month = root["month"].asUInt();
	Json::Value days;
	days = root["days"];
	for (uint32 i=0; i!=days.size(); ++i)
	{
		Json::Value &day = days[i];
		uint32 nDay = day["day"].asUInt();
		uint32 nSign = day["sign"].asUInt();
		pSign->mapDays.insert(std::make_pair(nDay, nSign));
	}
	pSign->day5 = root["day5"].asUInt();
	pSign->day10 = root["day10"].asUInt();
	pSign->day15 = root["day15"].asUInt();
	pSign->day20 = root["day20"].asUInt();
	pSign->dayAll = root["dayAll"].asUInt();
	
	pSign->total5 = root["total5"].asUInt();	
	pSign->total15 = root["total15"].asUInt();	
	pSign->total25 = root["total25"].asUInt();	
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateSigninInfoPacket(WorldPacket *packet, UserPtr &pUser, SigninStruct &ss, bool isFirstLogin)
{
	if(pUser.isNull() || !packet)
		return false;
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if (pChr.isNull())
		return false;
	packet->clear();
	packet->SetOpcode(SMSG_SIGNIN_LIST);
	*packet << uint16(SMSG_SIGNIN_LIST) << uint16(0);	
	*packet << uint32(sGLMgr.GetItemNum(pChr, ItemModel_BuQianKa));
	uint32 addCoins = 0;
	sVipCardMgr.AddLoginGift(pChr, addCoins);
	*packet << uint32(isFirstLogin ? addCoins : 0);
	*packet << (uint8)ss.month;
	*packet << (uint8)ss.mapDays.size();
	std::map<uint32, bool>::iterator mapi, endmapi = ss.mapDays.end();
	for (mapi = ss.mapDays.begin(); mapi != endmapi; ++ mapi)
	{
		*packet << (uint8)mapi->first;			
	}
	*packet << (uint8)ss.day5
			<< (uint8)ss.day10
			<< (uint8)ss.day15
			<< (uint8)ss.day20
			<< (uint8)ss.dayAll
			<< (uint8)ss.total5
			<< (uint8)ss.total15
			<< (uint8)ss.total25;
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateSigninResultPacket(WorldPacket *packet, const uint8 &opType, const uint8 &data1, const uint32 &coinsNum)
{
	if(!packet)
		return false;	
	packet->clear();
	packet->SetOpcode(SMSG_SIGNIN_OPERATION);
	*packet << uint16(SMSG_SIGNIN_OPERATION) << uint16(0);
	*packet << (uint8)opType
			<< (uint8)data1
			<< (uint32)coinsNum;
	packet->SetLength(packet->size());
	return true;
}

// 初始签到信息
bool CenterBankManager::InitCommonSign(UserPtr & pUser)
{
	if(pUser.isNull())
		return false;
	
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	
	uint32 platform_id = pUser->getUInt32Field("platform_id");
	
	GameBank pBank;
	if(!GetPublicData(platform_id, &pBank))
		return false;
	
	time_t t1 = time(0);
	tm t1Tm = *(localtime(&t1));
	// Log.Debug("CenterBankManager::InitCommonSign","wday[%u] mday[%u] info[%s]", t1Tm.tm_wday, t1Tm.tm_mday, pBank.info.c_str());
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(pBank.info, val);
	
	if(!val.isMember("sign"))
	{// 初始签到节点
		stCommonSignInfo csi = sXmlDataMgr.GetCommonSignInfo(pUser->getUInt32Field("reg_from"), pUser->getUInt32Field("gz_id"));
		if(csi.agent_id == 0)
			return false;
		
		stCommonSign cs;
		cs.agent_id = csi.agent_id;
		cs.gz_id = csi.gz_id;
		cs.sign_mode = csi.sign_mode;
		cs.sign_sub_mode = csi.sign_sub_mode;
		cs.update_combo_mode = csi.update_combo_mode;
		cs.update_bounty_mode = csi.update_bounty_mode;
		cs.agent_name = csi.agent_name;
		cs.last_updateTime = 0;
		
		if(csi.vSignInfo.size())
		{// 基础签到
			std::vector<stCommonSingleSignInfo>::iterator iter, ei = csi.vSignInfo.end();
			for(iter = csi.vSignInfo.begin(); iter!=ei; ++iter)
			{
				stCommonSingleSignResult csr;
				csr.stCSS.week = (*iter).week;
				csr.stCSS.month = (*iter).month;
				csr.stCSS.day = (*iter).day;
				csr.stCSS.days = (*iter).days;
				
				csr.stCSS.desc = (*iter).desc;
				csr.stCSS.mapBounties = (*iter).mapBounties;
				
				Log.Debug("CenterBankManager::InitCommonSign","update_combo_mode[%u] sign_sub_mode[%u] tm_wday[%u] week[%u]", 
									csi.update_combo_mode, csi.sign_sub_mode, t1Tm.tm_wday, (*iter).week);
				
				csr.status = enCommonSignStatus_NotGet;
				if(csi.update_combo_mode == 1)
				{// 周签到
					if(csi.sign_sub_mode == 1)
					{// 固定日期签到
						if(t1Tm.tm_wday == 0 && (*iter).week == 7)
						{// 周日
							csr.status = enCommonSignStatus_CanGet;
						}
						else
						{
							if(uint32(t1Tm.tm_wday) == (*iter).week)
							{// 新的一天可领
								csr.status = enCommonSignStatus_CanGet;
							}
							else
							{// 设置过期签到
								if(uint32(t1Tm.tm_wday) > (*iter).week)
									csr.status = enCommonSignStatus_TimesOver;
							}
						}
					}
					else
					{// 周期内次数签到
						if((*iter).days == 1)
							csr.status = enCommonSignStatus_CanGet;
					}
				}
				else
				{// 月签到
					if(csi.sign_sub_mode == 1)
					{// 固定日期签到
						if(uint32(t1Tm.tm_mday) == (*iter).day)
							csr.status = enCommonSignStatus_CanGet;
					}
					else
					{
						if((*iter).days == 1)
							csr.status = enCommonSignStatus_CanGet;
					}
				}
				cs.vSignInfo.push_back(csr);
			}
		}
		
		if(csi.vComboInfo.size())
		{// 连签信息
			std::vector<stCommonSingleSignInfo>::iterator iter, ei = csi.vComboInfo.end();
			for(iter = csi.vComboInfo.begin(); iter!=ei; ++iter)
			{
				stCommonSingleSignResult csr;
				csr.status = enCommonSignStatus_NotGet;
				csr.stCSS.week = (*iter).week;
				csr.stCSS.month = (*iter).month;
				csr.stCSS.day = (*iter).day;
				csr.stCSS.days = (*iter).days;
				
				csr.stCSS.desc = (*iter).desc;
				csr.stCSS.mapBounties = (*iter).mapBounties;
				
				cs.vComboInfo.push_back(csr);
			}
		}
		
		if(csi.vCountInfo.size())
		{// 累签信息
			std::vector<stCommonSingleSignInfo>::iterator iter, ei = csi.vCountInfo.end();
			for(iter = csi.vCountInfo.begin(); iter!=ei; ++iter)
			{
				stCommonSingleSignResult csr;
				csr.status = enCommonSignStatus_NotGet;
				csr.stCSS.week = (*iter).week;
				csr.stCSS.month = (*iter).month;
				csr.stCSS.day = (*iter).day;
				csr.stCSS.days = (*iter).days;
				
				csr.stCSS.desc = (*iter).desc;
				csr.stCSS.mapBounties = (*iter).mapBounties;
				
				cs.vCountInfo.push_back(csr);
			}
		}
		
		val["sign"] = CommonSignStructToJson(cs);
		
		Json::FastWriter w;
		pBank.info = w.write(val);
		sChannelMgr.updateBankDB(&pBank);
		
		// 发送签到信息
		WorldPacket packet;
		if(sProtocolsMgr.CreateCommonSignInfoPacket(&packet, cs))
			sGLMgr.SendProtocolsToChr(pChr, &packet);
	}
	else
	{// 判断更新时间，更新签到状态
		bool bUpdateData = false;
		uint32 time_now = time(0);			// 当前时间
		do
		{
			uint32 last_updateTime = val["sign"]["last_updateTime"].asUInt();	// 最后一次签到时间
			uint8 update_mode = val["sign"]["update_combo_mode"].asUInt();		// 签到更新类型
			uint8 sign_sub_mode = val["sign"]["sign_sub_mode"].asUInt();		// 签到子类型
			if(sTools.IsSameDay(last_updateTime, time_now))
			{// 同一天更新的，不判断是否需要更新
				break;
			}
			else
			{// 更新当日签到状态
				if(sTools.GetDifferDay(last_updateTime, time_now))
				{// 签到时间间隔超过一天，断掉连签天数
					val["sign"]["combo_days"] = 0;
					bUpdateData = true;
				}
				
				if(val["sign"].isMember("sign_info"))
				{// 基础签到信息
					bool bInitBounty = false;
					for (Json::Value::iterator iterV=val["sign"]["sign_info"].begin(); iterV!=val["sign"]["sign_info"].end(); ++iterV)
					{
						if(sign_sub_mode == 1)
						{// 固定日期签到
							if(update_mode == 1)
							{// 周签到
								if(t1Tm.tm_wday == 0 && (*iterV)["week"].asUInt() == 7)
								{// 周日
									(*iterV)["status"] = enCommonSignStatus_CanGet;
									bUpdateData = true;
								}
								else
								{
									// Log.Debug("CenterBankManager::InitCommonSign","tm_wday[%u] week[%u]", t1Tm.tm_wday, (*iterV)["week"].asUInt());
									if(uint32(t1Tm.tm_wday) == uint32((*iterV)["week"].asUInt()))
									{
										(*iterV)["status"] = enCommonSignStatus_CanGet;
										bUpdateData = true;
									}
									else
									{
										if((*iterV)["status"].asUInt() == enCommonSignStatus_CanGet)
										{// 前一天可领的更新为过期
											(*iterV)["status"] = enCommonSignStatus_TimesOver;
											bUpdateData = true;
										}
									}
								}
							}
							else
							{// 月签到
								if(uint32(t1Tm.tm_mday) == (*iterV)["day"].asUInt())
								{
									(*iterV)["status"] = enCommonSignStatus_CanGet;
									bUpdateData = true;
								}
								else
								{
									if((*iterV)["status"].asUInt() == enCommonSignStatus_CanGet)
									{
										(*iterV)["status"] = enCommonSignStatus_TimesOver;
										bUpdateData = true;
									}
								}
							}
						}
						else
						{// 次数签到
							if((*iterV)["status"] == enSignStatus_NotGet && !bInitBounty)
							{
								(*iterV)["status"] = enSignStatus_CanGet;
								bInitBounty = true;
							}
						}
					}
				}
			}
			
			if(update_mode == 1)
			{// 周更新
				if(sTools.IsSameWeek(time_now, last_updateTime))
				{
					break;
				}
			}
			else if(update_mode == 2)
			{// 月更新
				if(sTools.IsSameMonth(time_now, last_updateTime))
				{
					break;
				}
			}
			
			if(val["sign"].isMember("sign_info"))
			{// 基础签到信息
				for (Json::Value::iterator iterV=val["sign"]["sign_info"].begin(); iterV!=val["sign"]["sign_info"].end(); ++iterV)
				{
					(*iterV)["status"] = 0;
					if(sign_sub_mode == 1)
					{// 固定日期签到
						if(update_mode == 1)
						{// 周签到
							if(t1Tm.tm_wday == 0 && (*iterV)["week"].asUInt() == 7)
							{// 周日
								(*iterV)["status"] = enCommonSignStatus_CanGet;
								bUpdateData = true;
							}
							else
							{
								if(uint32(t1Tm.tm_wday) == (*iterV)["week"].asUInt())
								{
									(*iterV)["status"] = enCommonSignStatus_CanGet;
									bUpdateData = true;
								}
							}
						}
						else
						{// 月签到
							if(uint32(t1Tm.tm_mday) == (*iterV)["day"].asUInt())
							{
								(*iterV)["status"] = enCommonSignStatus_CanGet;
								bUpdateData = true;
							}
						}
					}
					else
					{// 次数签到
						if((*iterV)["days"] == 1)
							(*iterV)["status"] = enCommonSignStatus_CanGet;
					}
				}
			}
			
			val["sign"]["last_updateTime"] = time_now;
			
		}while(0);
		
		do
		{
			uint32 last_updateComboTime = val["sign"]["last_updateComboTime"].asUInt();		// 最后一次连签累签时间
			if(sTools.IsSameDay(last_updateComboTime, time_now))
			{// 同一天更新的，不判断是否需要更新
				break;
			}
			
			uint8 update_mode = val["sign"]["update_bounty_mode"].asUInt();		// 连签累签更新模式
			if(update_mode == 1)
			{// 周更新
				if(sTools.IsSameWeek(time_now, last_updateComboTime))
				{
					break;
				}
			}
			else if(update_mode == 2)
			{// 月更新
				if(sTools.IsSameMonth(time_now, last_updateComboTime))
				{
					break;
				}
			}
			
			if(val["sign"].isMember("sign_combo"))
			{// 连续签到信息
				for (Json::Value::iterator iterV=val["sign"]["sign_combo"].begin(); iterV!=val["sign"]["sign_combo"].end(); ++iterV)
				{
					(*iterV)["status"] = enCommonSignStatus_NotGet;
					val["sign"]["combo_days"] = 0;
					bUpdateData = true;
				}
			}
			
			if(val["sign"].isMember("sign_count"))
			{// 累计签到信息
				for (Json::Value::iterator iterV=val["sign"]["sign_count"].begin(); iterV!=val["sign"]["sign_count"].end(); ++iterV)
				{
					(*iterV)["status"] = enCommonSignStatus_NotGet;
					val["sign"]["count_days"] = 0;
					bUpdateData = true;
				}
			}
			
			val["sign"]["last_updateComboTime"] = time_now;
		}while(0);
		
		Json::FastWriter w;
		if(bUpdateData)
		{
			pBank.info = w.write(val);
			
			sChannelMgr.updateBankDB(&pBank);
		}
		
		stCommonSign cs;
		JsonToCommonSignStruct(val, cs);
		
		// 发送签到信息
		WorldPacket packet;
		if(sProtocolsMgr.CreateCommonSignInfoPacket(&packet, cs))
			sGLMgr.SendProtocolsToChr(pChr, &packet);
	}
	
	return true;
}

// 公共签到
bool CenterBankManager::GetCommonSign(UserPtr & pUser, const uint32 & type, const uint32 & data)
{
	if(pUser.isNull())
		return false;
	
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	
	GameBank bank;
	GetPublicData(pUser, &bank);
	
	Json::Value val, valSign;
	Json::Reader reader;
	reader.parse(bank.info, val);
	if(!val.isMember("sign"))
		return false;
	
	valSign = val["sign"];
	
	stCommonSign cs;
	JsonToCommonSignStruct(val, cs);
	
	bool bSucess = false;
	
	if(type == 1)
	{// 日签
		std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vSignInfo.end();
		for(iter = cs.vSignInfo.begin(); iter!=ei; ++iter)
		{
			if((*iter).status == enSignStatus_CanGet)
			{
				std::map<uint32, uint32>::iterator itB, eiB = (*iter).stCSS.mapBounties.end();
				for(itB = (*iter).stCSS.mapBounties.begin(); itB!=eiB; ++itB)
				{
					sGLMgr.addItemNum(pChr, itB->first, itB->second);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, itB->first, en_UNT_Add, itB->second, en_HSI_Signin, type, data);
				}
				
				(*iter).status = enSignStatus_Get;
				
				// 连签增加
				cs.combo_days++;
				// 累签增加
				cs.count_days++;
				cs.last_updateTime = time(0);
				
				bSucess = true;
				Log.Debug("CenterBankManager::GetCommonSign","week[%u] status[%u]", (*iter).stCSS.week, (*iter).status);
				break;
			}
		}
		
		// 判断连签
		std::vector<stCommonSingleSignResult>::iterator iterCombo, eiCombo = cs.vComboInfo.end();
		for(iterCombo = cs.vComboInfo.begin(); iterCombo!=eiCombo; ++iterCombo)
		{
			if((*iterCombo).stCSS.days == cs.combo_days && (*iterCombo).status == enSignStatus_NotGet)
			{
				(*iterCombo).status = enSignStatus_CanGet;
			}
		}
		
		// 判断累签
		std::vector<stCommonSingleSignResult>::iterator iterCount, eiCount = cs.vCountInfo.end();
		for(iterCount = cs.vCountInfo.begin(); iterCount!=eiCount; ++iterCount)
		{
			if((*iterCount).stCSS.days == cs.count_days && (*iterCount).status == enSignStatus_NotGet)
			{
				(*iterCount).status = enSignStatus_CanGet;
			}
		}
	}
	else if(type == 2)
	{// 连签
		std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vComboInfo.end();
		for(iter = cs.vComboInfo.begin(); iter!=ei; ++iter)
		{
			if((*iter).status == enSignStatus_CanGet && (*iter).stCSS.days == data)
			{
				std::map<uint32, uint32>::iterator itB, eiB = (*iter).stCSS.mapBounties.end();
				for(itB = (*iter).stCSS.mapBounties.begin(); itB!=eiB; ++itB)
				{
					sGLMgr.addItemNum(pChr, itB->first, itB->second);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, itB->first, en_UNT_Add, itB->second, en_HSI_Signin, type, data);
				}
				
				(*iter).status = enSignStatus_Get;
				bSucess = true;
				break;
			}
		}
	}
	else if(type == 3)
	{// 累签
		std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vCountInfo.end();
		for(iter = cs.vCountInfo.begin(); iter!=ei; ++iter)
		{
			if((*iter).status == enSignStatus_CanGet && (*iter).stCSS.days == data)
			{
				std::map<uint32, uint32>::iterator itB, eiB = (*iter).stCSS.mapBounties.end();
				for(itB = (*iter).stCSS.mapBounties.begin(); itB!=eiB; ++itB)
				{
					sGLMgr.addItemNum(pChr, itB->first, itB->second);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, itB->first, en_UNT_Add, itB->second, en_HSI_Signin, type, data);
				}
				
				(*iter).status = enSignStatus_Get;
				bSucess = true;
				break;
			}
		}
	}
	else
	{// 补签
		std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vSignInfo.end();
		for(iter = cs.vSignInfo.begin(); iter!=ei; ++iter)
		{
			if((*iter).status == enSignStatus_CanGet && (*iter).stCSS.days == data)
			{
				std::map<uint32, uint32>::iterator itB, eiB = (*iter).stCSS.mapBounties.end();
				for(itB = (*iter).stCSS.mapBounties.begin(); itB!=eiB; ++itB)
				{
					sGLMgr.addItemNum(pChr, itB->first, itB->second);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, itB->first, en_UNT_Add, itB->second, en_HSI_Signin, type, data);
				}
				
				(*iter).status = enSignStatus_Get;
				bSucess = true;
				break;
			}
		}
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCommonSignResultPacket(&packet, type, data, bSucess))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	if(bSucess)
	{
		val["sign"] = CommonSignStructToJson(cs);
		Json::FastWriter w;
		bank.info = w.write(val);
		Log.Debug("CenterBankManager::GetCommonSign","bank.info[%s] cs.last_updateTime[%u]", bank.info.c_str(), cs.last_updateTime);
		sChannelMgr.updateBankDB(&bank);
		
		if(sProtocolsMgr.CreateCommonSignInfoPacket(&packet, cs))
			sGLMgr.SendProtocolsToChr(pChr, &packet);
	}
	
	return false;
}

// 公共签到结构体转JSON
Json::Value CenterBankManager::CommonSignStructToJson(stCommonSign & cs)
{
	Json::Value val;
	
	val["agent_id"] = cs.agent_id;
	val["gz_id"] = cs.gz_id;
	val["sign_mode"] = cs.sign_mode;
	val["sign_sub_mode"] = cs.sign_sub_mode;
	val["update_combo_mode"] = cs.update_combo_mode;
	val["agent_name"] = cs.agent_name;
	val["update_bounty_mode"] = cs.update_bounty_mode;
	val["last_updateTime"] = cs.last_updateTime;
	val["combo_days"] = cs.combo_days;
	val["count_days"] = cs.count_days;
	val["last_updateComboTime"] = cs.last_updateComboTime;
	
	if(cs.vSignInfo.size())
	{// 基础签到
		uint8 index = 0;
		std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vSignInfo.end();		
		for(iter = cs.vSignInfo.begin(); iter!=ei; ++iter)
		{
			Json::Value valSign;
			valSign["status"] = (*iter).status;			// 签到状态（0 未签 1 已签）
			valSign["week"] = (*iter).stCSS.week;		// 周
			valSign["month"] = (*iter).stCSS.month;		// 月
			valSign["day"] = (*iter).stCSS.day;			// 日
			valSign["days"] = (*iter).stCSS.days;		// 天数
			valSign["desc"] = (*iter).stCSS.desc;		// 描述
			
			uint8 bounty_index = 0;						// 奖励索引
			std::map<uint32, uint32>::iterator itB, eiB = (*iter).stCSS.mapBounties.end();
			for(itB = (*iter).stCSS.mapBounties.begin(); itB!=eiB; ++itB)
			{
				Json::Value valBounty;
				valBounty["bounty_modelid"] = itB->first;
				valBounty["bounty_num"] = itB->second;
				
				valSign["bounty"][bounty_index++] = valBounty;
			}
			
			val["sign_info"][index++] = valSign;
		}
	}
	
	if(cs.vComboInfo.size())
	{// 连签信息
		uint8 index = 0;
		std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vComboInfo.end();		
		for(iter = cs.vComboInfo.begin(); iter!=ei; ++iter)
		{
			Json::Value valSign;
			valSign["status"] = (*iter).status;			// 签到状态（0 未签 1 已签）
			valSign["week"] = (*iter).stCSS.week;		// 周
			valSign["month"] = (*iter).stCSS.month;		// 月
			valSign["day"] = (*iter).stCSS.day;			// 日
			valSign["days"] = (*iter).stCSS.days;		// 天数
			valSign["desc"] = (*iter).stCSS.desc;		// 描述
			
			uint8 bounty_index = 0;						// 奖励索引
			std::map<uint32, uint32>::iterator itB, eiB = (*iter).stCSS.mapBounties.end();
			for(itB = (*iter).stCSS.mapBounties.begin(); itB!=eiB; ++itB)
			{
				Json::Value valBounty;
				valBounty["bounty_modelid"] = itB->first;
				valBounty["bounty_num"] = itB->second;
				
				valSign["bounty"][bounty_index++] = valBounty;
			}
			
			val["sign_combo"][index++] = valSign;
		}
	}
	
	if(cs.vCountInfo.size())
	{// 累签信息
		uint8 index = 0;
		std::vector<stCommonSingleSignResult>::iterator iter, ei = cs.vCountInfo.end();		
		for(iter = cs.vCountInfo.begin(); iter!=ei; ++iter)
		{
			Json::Value valSign;
			valSign["status"] = (*iter).status;			// 签到状态（0 未签 1 已签）
			valSign["week"] = (*iter).stCSS.week;		// 周
			valSign["month"] = (*iter).stCSS.month;		// 月
			valSign["day"] = (*iter).stCSS.day;			// 日
			valSign["days"] = (*iter).stCSS.days;		// 天数
			valSign["desc"] = (*iter).stCSS.desc;		// 描述
			
			uint8 bounty_index = 0;						// 奖励索引
			std::map<uint32, uint32>::iterator itB, eiB = (*iter).stCSS.mapBounties.end();
			for(itB = (*iter).stCSS.mapBounties.begin(); itB!=eiB; ++itB)
			{
				Json::Value valBounty;
				valBounty["bounty_modelid"] = itB->first;
				valBounty["bounty_num"] = itB->second;
				
				valSign["bounty"][bounty_index++] = valBounty;
			}
			
			val["sign_count"][index++] = valSign;
		}
	}
	
	return val;
}

// JSON转公共签到结构体
bool CenterBankManager::JsonToCommonSignStruct(const Json::Value & valJson, stCommonSign & cs)
{
	// 签到节点不存在
	if(!valJson.isMember("sign"))
		return false;
	
	Json::Value val = valJson["sign"];
	cs.agent_id = val["agent_id"].asUInt();
	cs.gz_id = val["gz_id"].asUInt();
	cs.sign_mode = val["sign_mode"].asUInt();
	cs.sign_sub_mode = val["sign_sub_mode"].asUInt();
	cs.update_combo_mode = val["update_combo_mode"].asUInt();
	cs.update_bounty_mode = val["update_bounty_mode"].asUInt();
	cs.agent_name = val["agent_name"].asString();
	cs.combo_days = val["combo_days"].asUInt();
	cs.count_days = val["count_days"].asUInt();
	cs.last_updateComboTime = val["last_updateComboTime"].asUInt();
	
	if(val.isMember("sign_info"))
	{// 基础签到信息
		for (Json::Value::iterator iterV=val["sign_info"].begin(); iterV!=val["sign_info"].end(); ++iterV)
		{
			stCommonSingleSignResult css;
			css.stCSS.week = (*iterV)["week"].asUInt();
			css.stCSS.month = (*iterV)["month"].asUInt();
			css.stCSS.day = (*iterV)["day"].asUInt();
			css.stCSS.days = (*iterV)["days"].asUInt();
			css.stCSS.desc = (*iterV)["desc"].asString();
			css.status = (*iterV)["status"].asUInt();
			
			for (Json::Value::iterator iterV2=(*iterV)["bounty"].begin(); iterV2!=(*iterV)["bounty"].end(); ++iterV2)
			{
				css.stCSS.mapBounties.insert(std::make_pair((*iterV2)["bounty_modelid"].asUInt(), (*iterV2)["bounty_num"].asUInt()));
			}
			
			cs.vSignInfo.push_back(css);
		}
	}
	
	if(val.isMember("sign_combo"))
	{// 连续签到信息
		for (Json::Value::iterator iterV=val["sign_combo"].begin(); iterV!=val["sign_combo"].end(); ++iterV)
		{
			stCommonSingleSignResult css;
			css.stCSS.week = (*iterV)["week"].asUInt();
			css.stCSS.month = (*iterV)["month"].asUInt();
			css.stCSS.day = (*iterV)["day"].asUInt();
			css.stCSS.days = (*iterV)["days"].asUInt();
			css.stCSS.desc = (*iterV)["desc"].asString();
			css.status = (*iterV)["status"].asUInt();
			
			for (Json::Value::iterator iterV2=(*iterV)["bounty"].begin(); iterV2!=(*iterV)["bounty"].end(); ++iterV2)
			{
				css.stCSS.mapBounties.insert(std::make_pair((*iterV2)["bounty_modelid"].asUInt(), (*iterV2)["bounty_num"].asUInt()));
			}
			
			cs.vComboInfo.push_back(css);
		}
	}
	
	if(val.isMember("sign_count"))
	{// 累计签到信息
		for (Json::Value::iterator iterV=val["sign_count"].begin(); iterV!=val["sign_count"].end(); ++iterV)
		{
			stCommonSingleSignResult css;
			css.stCSS.week = (*iterV)["week"].asUInt();
			css.stCSS.month = (*iterV)["month"].asUInt();
			css.stCSS.day = (*iterV)["day"].asUInt();
			css.stCSS.days = (*iterV)["days"].asUInt();
			css.stCSS.desc = (*iterV)["desc"].asString();
			css.status = (*iterV)["status"].asUInt();
			
			for (Json::Value::iterator iterV2=(*iterV)["bounty"].begin(); iterV2!=(*iterV)["bounty"].end(); ++iterV2)
			{
				css.stCSS.mapBounties.insert(std::make_pair((*iterV2)["bounty_modelid"].asUInt(), (*iterV2)["bounty_num"].asUInt()));
			}
			
			cs.vCountInfo.push_back(css);
		}
	}
	
	return true;
}

//===========================公共签名===================================
bool CenterBankManager::CommonSignName(CharPtr & pChr, const uint32 & platform_id, String & content)
{
	if(pChr.isNull())
		return false;
	
	GameBank pBank;
	if(GetRealBank(platform_id, pBank) != enGetPlayerInfoByPid_Sucess)
		return false;
	
	pBank.sdata2 = content;
	sChannelMgr.updateBankDB(&pBank);
	
	// 刷新排行数据
	sGLMgr.UpdateCommonPlayerQueueTop();
	return true;
}

bool CenterBankManager::GetCommonSignName(CharPtr & pChr, const uint32 & platform_id)
{
	if(pChr.isNull())
		return false;
	
	GameBank pBank;
	if(GetRealBank(platform_id, pBank) != enGetPlayerInfoByPid_Sucess)
		return false;
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateCommonSignNamePacket(&packet, platform_id, pBank.sdata2))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	return true;
}

//-------------------------------------------------------------------
void CenterBankManager::UserLogin(UserPtr &pUser)
{
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if (pChr.isNull())
		return;
	WSSocketPtr pSocket = pChr->getSocket();
	if (pSocket.isNull())
		return;
	WorldPacket packet;
	GameBank bank;
	GetPublicData(pUser, &bank);	
	// 签到数据
	String strJson = bank.sdata1;
	SigninStruct ss;
	SigninOfJsonToStruct(strJson, &ss);	
	time_t nt = time(0);
	tm ttm = *localtime(&nt);
	if (ss.month != (uint32)ttm.tm_mon)
	{// 不是同月,重置
		ss.Init();
		ss.month = ttm.tm_mon;
		String strJson = SigninOfStructToJson(ss);
		CenterDatabase.WaitExecute("update game_bank set `sdata1`='%s' where `bank_id` = %u", strJson.c_str(), bank.bank_id);	
	}	
	bool isFirstLogin = false, isSaveDB = false;;
	std::map<uint32, bool>::iterator iter = ss.mapDays.find(ttm.tm_mday);
	if (iter == ss.mapDays.end())
		isFirstLogin = true;
	if (CreateSigninInfoPacket(&packet, pUser, ss, isFirstLogin))
		pSocket->SendPacket(&packet);
	// 黄钻登录奖励标记
	uint32 last_lltime = GetUserDataVal(bank, "HZDLLB");
	if (last_lltime && !sTools.IsSameDay(last_lltime, nt)){
		SetUserDataVal(bank, "HZDLLB", 0);
		isSaveDB = true;
	}
	// 福利勋章礼包	
	if (sVipCardMgr.HaveWelfare(pChr))
	{
		uint32 last_welfaretime = GetUserDataVal(bank, "FLXZLB");
		if (!sTools.IsSameDay(last_welfaretime, nt))
		{
			SetUserDataVal(bank, "FLXZLB", 0);
			sGLMgr.NoticeWelfare(pChr);
			isSaveDB = true;
		}
	}
	if (isSaveDB)
		SaveUserDataDB(bank);
}
//-------------------------------------------------------------------
uint32 CenterBankManager::GetUserDataVal(const GameBank &pBank, const String &strKey)
{
	String strJson = pBank.user_data;
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	if (root.isMember(strKey))
		return root[strKey].asUInt();	
	return 0;
}
//-------------------------------------------------------------------
String CenterBankManager::GetUserDataString(const GameBank &pBank, const String &strKey)
{
	String strJson = pBank.user_data;
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	if (root.isMember(strKey))
		return root[strKey].asString();	
	return "";
}
//-------------------------------------------------------------------
Json::Value CenterBankManager::GetUserDataJson(const GameBank &pBank, const String &strKey)
{
	String strJson = pBank.user_data;
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	if (root.isMember(strKey))
		return root[strKey];	
	Json::Value tmp;
	return tmp;
}
//-------------------------------------------------------------------
void CenterBankManager::SetUserDataVal(GameBank &pBank, const String &strKey, const uint32 &val)
{
	String strJson = pBank.user_data;
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	root[strKey.c_str()] = Json::Value(val);
	Json::StyledWriter styWriter;
	pBank.user_data = styWriter.write(root);	
}
//-------------------------------------------------------------------
void CenterBankManager::SetUserDataString(GameBank &pBank, const String &strKey, const String &val)
{
	String strJson = pBank.user_data;
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	root[strKey.c_str()] = Json::Value(val);
	Json::StyledWriter styWriter;
	pBank.user_data = styWriter.write(root);	
}
//-------------------------------------------------------------------
void CenterBankManager::SetUserDataJson(GameBank &pBank, const String &strKey, const Json::Value &val)
{
	String strJson = pBank.user_data;
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	root[strKey.c_str()] = val;
	Json::StyledWriter styWriter;
	pBank.user_data = styWriter.write(root);	
}
//-------------------------------------------------------------------
void CenterBankManager::SaveUserDataDB(const GameBank &pBank)
{
	CenterDatabase.WaitExecute("update game_bank set `user_data`='%s' where `bank_id` = %u", pBank.user_data.c_str(), pBank.bank_id);
}
//-------------------------------------------------------------------
void 	CenterBankManager::HappyFarmJsonToStruct(const String &strJson, std::list<HappyFarmItem> *pList)
{
	pList->clear();
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJson, root);
	for (uint32 i=0; i!=root.size(); ++i)
	{
		Json::Value &child = root[i];
		HappyFarmItem hfi;
		hfi.id = child["id"].asUInt();
		hfi.model_id = child["model_id"].asUInt();
		hfi.begin_time = child["begin_time"].asUInt();
		hfi.end_time = child["end_time"].asUInt();
		pList->push_back(hfi);
	}
}
//-------------------------------------------------------------------
String 	CenterBankManager::HappyFarmStructToJson(std::list<HappyFarmItem> &lstHappyFarm)
{
	Json::Value root;
	Json::StyledWriter styWriter;
	std::list<HappyFarmItem>::iterator iter, enditer = lstHappyFarm.end();
	for (iter = lstHappyFarm.begin(); iter != enditer; ++ iter)
	{
		HappyFarmItem &hfi = *iter;
		Json::Value child;
		child["id"] = Json::Value(uint32(hfi.id));
		child["model_id"] = Json::Value(uint32(hfi.model_id));
		child["begin_time"] = Json::Value(uint32(hfi.begin_time));
		child["end_time"] = Json::Value(uint32(hfi.end_time));
		root.append(child);
	}
	return styWriter.write(root);
}
//-------------------------------------------------------------------
void 	CenterBankManager::SaveHappyFarmDB(const GameBank &bank)
{
	CenterDatabase.WaitExecute("update game_bank set `sdata2` = '%s' where `bank_id` = %u", bank.sdata2.c_str(), bank.bank_id);
}
//-------------------------------------------------------------------
void 	CenterBankManager::HappyFarmBusiness(UserPtr &pUser, const uint32 &opType, const uint32 &farmId, const uint32 &number)
{
WGS_HAPPY_FARM_INNER_LOCK
	if (pUser.isNull())
		return;
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if (pChr.isNull())
		return;
	WSSocketPtr pSocket = pChr->getSocket();
	if (pSocket.isNull())
		return;
	GameBank bank;
	GetPublicData(pUser, &bank);
	std::list<HappyFarmItem> lstHFI;
	HappyFarmJsonToStruct(bank.sdata2, &lstHFI);
	bool isUpdate = false;
	uint32 getCoins = 0;
	uint8 result = 0;
	String szName = "";
	WorldPacket packet;
	if (opType)
	{// 卖
		Log.Debug("CenterBankManager::HappyFarmBusiness 111","char[%u] opType[%u] farmId[%u]",pChr->getHandle(),opType,farmId);
		uint32 nt = time(0);
		uint32 farm_modelID = 0;
		std::list<HappyFarmItem>::iterator iter, enditer = lstHFI.end();
		for (iter = lstHFI.begin(); iter != enditer; ++ iter)
		{
			HappyFarmItem &hfi = *iter;
			if (hfi.id == farmId)
			{// 找到，加钱
				const HappyFarm* pHf = sXmlDataMgr.GetHappyFarm(hfi.model_id);
				if (pHf == NULL)
					return;
				
				farm_modelID = hfi.model_id;
				
				szName = pHf->szName;
				getCoins = pHf->price;
				if (nt >= hfi.end_time){
					getCoins += pHf->earnings;
				}
				Log.Debug("CenterBankManager::HappyFarmBusiness 222","char[%u] opType[%u] farmId[%u] model_id[%u] price[%u] getCoins[%u]",
							pChr->getHandle(),opType,farmId,hfi.model_id,pHf->price,getCoins);
				sGLMgr.addItemNum(pChr, ItemModel_Coins, getCoins);
				sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_HappyFarm, ItemModel_Coins, en_UNT_Add, getCoins, pHf->model_id);
				HappyFarmLog(bank.platform_id, bank.nick, 0, "", pHf->model_id, pHf->szName, 1, getCoins);
				lstHFI.erase(iter);
				// 统计牧场动物变化日志
				UpdateFramTransLog(pChr,en_FLS_BuySell,en_UNT_Reduce,farm_modelID,1,lstHFI);
				isUpdate = true;
				break;
			}
		}
	}
	else
	{// 买
		const HappyFarm* pHf = sXmlDataMgr.GetHappyFarm(farmId);
		if (pHf == NULL || number == 0)
			return;
		if (pChr->getStatus() != CharacterStatusFree)
			return;
		szName = pHf->szName;
		uint32 max_num = sXmlDataMgr.GetConfXMLValue("HF_MAX_ANIMAL");
		if (lstHFI.size()+number > max_num){
			result = 3;
		}
		else if (lstHFI.size() >= max_num)
			result = 2;
		else
		{
			getCoins = pHf->price * number;
			if (sGLMgr.reduceItemNum(pChr, ItemModel_Coins, getCoins))
			{			
				sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_HappyFarm, ItemModel_Coins, en_UNT_Reduce, getCoins, pHf->model_id, number);	
				HappyFarmLog(0, "", bank.platform_id, bank.nick, pHf->model_id, pHf->szName, number, getCoins);				
				uint32 nt = time(0);
				for (uint32 i=0; i!=number; ++i)
				{
					HappyFarmItem hfi;
					hfi.id = now() + RandomUInt();
					hfi.model_id = farmId;
					hfi.begin_time = nt;
					hfi.end_time = nt + pHf->feeding_cycle * 86400;
					lstHFI.push_back(hfi);
					isUpdate = true;
					if (CreateSingleFarmPacket(&packet, hfi))
						pSocket->SendPacket(&packet);
				}
				
				// 统计牧场动物变化日志
				UpdateFramTransLog(pChr,en_FLS_BuySell,en_UNT_Add,farmId,number,lstHFI);
			}
			else
				result = 1;
		}
		
	}
	// 发数据包	
	if (CreateBusinessHappyFarmPacket(&packet, result, opType, farmId, szName, number, getCoins))
		pSocket->SendPacket(&packet);
	// 转换成Json并SaveDB
	if (isUpdate)
	{
		bank.sdata2 = HappyFarmStructToJson(lstHFI);
		SaveHappyFarmDB(bank);
	}
}

// 将牧场动物列表转换为map结构
void CenterBankManager::UpdateFramTransLog(CharPtr & pChr,const uint8 & sub_type,const uint8 & op_type,
											const uint32 & model_id,const uint32 & num,
											std::list<HappyFarmItem> farms,const uint32 & destPId)
{
	if(pChr.isNull())
		return ;
	
	std::map<uint32,uint32> mapFarms;
	std::map<uint32, HappyFarm> mapHappyFarm;
	sXmlDataMgr.GetHappyFarmList(mapHappyFarm);
	
	std::map<uint32,HappyFarm>::iterator itFarm,eiFarm = mapHappyFarm.end();
	for(itFarm = mapHappyFarm.begin(); itFarm!=eiFarm; ++itFarm)
	{
		mapFarms.insert(std::make_pair(itFarm->first,0));
	}
	
	std::list<HappyFarmItem>::iterator iter,ei = farms.end();
	for(iter = farms.begin(); iter!=ei; ++iter)
	{
		uint32 model_id = (*iter).model_id;
		std::map<uint32,uint32>::iterator fit = mapFarms.find(model_id);
		if(fit != mapFarms.end())
			fit->second++;
	}
	
	// 记录动物变化日志
	UpdateFarmInfoLog(pChr,sub_type,op_type,model_id,num,mapFarms,destPId);
	// 更新动物库存数量
	UpdateFarmNumber(pChr,mapFarms);
}

// 增加或减少牧场动物
void 	CenterBankManager::OperatorBusinedd(UserPtr &pUser, const uint32 &opType,const uint32 &farmId, const uint32 &number)
{
WGS_HAPPY_FARM_INNER_LOCK
	if (pUser.isNull())
		return;
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if (pChr.isNull())
		return;
	WSSocketPtr pSocket = pChr->getSocket();
	if (pSocket.isNull())
		return;
	GameBank bank;
	GetPublicData(pUser, &bank);
	std::list<HappyFarmItem> lstHFI;
	HappyFarmJsonToStruct(bank.sdata2, &lstHFI);
	bool bWantWrite = false;
	uint32 getCoins = 0;
	uint8 result = 0;
	String szName = "";
	WorldPacket packet;
	if (opType)
	{// 减少
		uint32 nt = time(0);
		std::list<HappyFarmItem>::iterator iter, enditer = lstHFI.end();
		for (iter = lstHFI.begin(); iter != enditer; ++ iter)
		{
			HappyFarmItem &hfi = *iter;
			if (hfi.id == farmId)
			{// 找到，加钱
				const HappyFarm* pHf = sXmlDataMgr.GetHappyFarm(hfi.model_id);
				if (pHf == NULL)
					return;
				szName = pHf->szName;
				getCoins = pHf->price;
				if (nt >= hfi.end_time){
					getCoins += pHf->earnings;
				}
				sGLMgr.addItemNum(pChr, ItemModel_Coins, getCoins);
				sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_HappyFarm, ItemModel_Coins, en_UNT_Add, getCoins, pHf->model_id);
				HappyFarmLog(bank.platform_id, bank.nick, 0, "", pHf->model_id, pHf->szName, 1, getCoins);
				lstHFI.erase(iter);
				bWantWrite = true;
				break;
			}
		}
	}
	else
	{// 增加
		const HappyFarm* pHf = sXmlDataMgr.GetHappyFarm(farmId);
		if (pHf == NULL || number == 0)
			return;
		if (pChr->getStatus() != CharacterStatusFree)
			return;
		szName = pHf->szName;
		uint32 max_num = sXmlDataMgr.GetConfXMLValue("HF_MAX_ANIMAL");
		if (lstHFI.size()+number > max_num){
			result = 3;
		}
		else if (lstHFI.size() >= max_num)
			result = 2;
		else
		{
			getCoins = pHf->price * number;
			if (sGLMgr.reduceItemNum(pChr, ItemModel_Coins, getCoins))
			{			
				sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_HappyFarm, ItemModel_Coins, en_UNT_Reduce, getCoins, pHf->model_id, number);	
				HappyFarmLog(0, "", bank.platform_id, bank.nick, pHf->model_id, pHf->szName, number, getCoins);				
				uint32 nt = time(0);
				for (uint32 i=0; i!=number; ++i)
				{
					HappyFarmItem hfi;
					hfi.id = now() + RandomUInt();
					hfi.model_id = farmId;
					hfi.begin_time = nt;
					hfi.end_time = nt + pHf->feeding_cycle * 86400;
					lstHFI.push_back(hfi);
					bWantWrite = true;
					if (CreateSingleFarmPacket(&packet, hfi))
						pSocket->SendPacket(&packet);
				}
			}
			else
				result = 1;
		}
	}
	// 发数据包	
	if (CreateBusinessHappyFarmPacket(&packet, result, opType, farmId, szName, number, getCoins))
		pSocket->SendPacket(&packet);
	// 转换成Json并SaveDB
	if (bWantWrite)
	{
		bank.sdata2 = HappyFarmStructToJson(lstHFI);
		SaveHappyFarmDB(bank);
	}
}

//-------------------------------------------------------------------
bool 	CenterBankManager::HappyFarmGiving(UserPtr &pUser, const uint32 &destPId, const uint32 &farmId)
{
WGS_HAPPY_FARM_INNER_LOCK
	if (pUser.isNull())
		return false;
	if (pUser->getUInt32Field("platform_id") == destPId)
		return false;
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if (pChr.isNull())
		return false;
	WSSocketPtr pSocket = pChr->getSocket();
	if (pSocket.isNull())
		return false;
	if (sXmlDataMgr.GetConfXMLValue("HAVE_VIP") && sVipCardMgr.GetUsedVipId(pChr) == 0)
		return false;
	uint8 result = 1;
	String szDestNick = "";
	WorldPacket packet;
	GameBank bank;
	GetPublicData(pUser, &bank);
	std::list<HappyFarmItem> lstHFI;
	HappyFarmJsonToStruct(bank.sdata2, &lstHFI);	
	std::list<HappyFarmItem>::iterator iter, enditer = lstHFI.end();
	for (iter = lstHFI.begin(); iter != enditer; ++ iter)
	{
		HappyFarmItem &hfi = *iter;
		if (hfi.id == farmId)
		{// 找到，赠送
			GameBank destBank;
			if (!GetPublicData(destPId, &destBank))
			{
				if (CreateGivingHappyFarmPacket(&packet, result, farmId, destPId, szDestNick))
					pSocket->SendPacket(&packet);
				return false;
			}
			szDestNick = destBank.nick;
			std::list<HappyFarmItem> lstDestHFI;
			HappyFarmJsonToStruct(destBank.sdata2, &lstDestHFI);
			if (lstDestHFI.size() < sXmlDataMgr.GetConfXMLValue("HF_MAX_ANIMAL"))
			{
				HappyFarmItem newHfi = hfi;
				const HappyFarm *pHf = sXmlDataMgr.GetHappyFarm(hfi.model_id);
				UserPtr pDestUser;
				std::list<UserPtr> lstUsers;
				if (sUserMgr.getUserList(&lstUsers, 0, 1, "platform_id=%u", destPId))
				{
					pDestUser = lstUsers.front();
					if (!pDestUser.isNull())
					{
						WSSocketPtr pSock = pDestUser->m_Socket.getResourcePtr();
						if (!pSock.isNull() && CreateSingleFarmPacket(&packet, newHfi))
							pSock->SendPacket(&packet);
					}
				}
				
				// 增加日志
				HappyFarmLog(bank.platform_id, bank.nick, destBank.platform_id, destBank.nick, pHf->model_id, pHf->szName, 1, 0);
				lstDestHFI.push_back(newHfi);			
				
				// 被赠送人动物变化日志
				if(!pDestUser.isNull())
				{
					Log.Debug("CenterBankManager::HappyFarmGiving","user[%u] get model_id[%u] from user[%u]",
										destPId,newHfi.model_id,pUser->getUInt32Field("platform_id"));
					CharPtr pDestChr = sCharMgr.load(pDestUser->getUInt32Field("char_id"));
					UpdateFramTransLog(pDestChr,en_FLS_SendGet,en_UNT_Add,newHfi.model_id,1,lstDestHFI,pUser->getUInt32Field("platform_id"));
				}
				
				destBank.sdata2 = HappyFarmStructToJson(lstDestHFI);
				SaveHappyFarmDB(destBank);
				lstHFI.erase(iter);
				
				// 赠送人动物变化日志
				Log.Debug("CenterBankManager::HappyFarmGiving","user pid[%u] send model_id[%u] to user pid[%u]",
									pUser->getUInt32Field("platform_id"),newHfi.model_id,destPId);
				UpdateFramTransLog(pChr,en_FLS_SendGet,en_UNT_Reduce,newHfi.model_id,1,lstHFI,destPId);
				
				result = 0;
			}
			else
				result = 2;
			break;
		}
	}
	if (CreateGivingHappyFarmPacket(&packet, result, farmId, destPId, szDestNick))
		pSocket->SendPacket(&packet);	
	if (result == 0)
	{
		bank.sdata2 = HappyFarmStructToJson(lstHFI);
		SaveHappyFarmDB(bank);
	}
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateMyHappyFarmPacket(WorldPacket *packet, std::list<HappyFarmItem> &pList)
{
	packet->clear();
	packet->SetOpcode(SMSG_GETPRAIRIE_LIST);
	*packet << uint16(SMSG_GETPRAIRIE_LIST) << uint16(0);	
	*packet << uint8(pList.size());
	uint32 nt = time(0);
	std::list<HappyFarmItem>::iterator iter, enditer = pList.end();
	for (iter = pList.begin(); iter != enditer; ++iter)
	{
		HappyFarmItem &pHfi = *iter;
		const HappyFarm* pHf = sXmlDataMgr.GetHappyFarm(pHfi.model_id);
		if (pHf == NULL)
			return false;
		*packet << uint32(pHfi.id);
		*packet << uint8(pHf->model_id);
		AppendPacketString<uint8>(packet, pHf->szName);
		*packet << uint32(nt);
		*packet << uint32(pHfi.begin_time);
		*packet << uint32(pHfi.end_time);
		*packet << uint32(pHf->price);
		*packet << uint32(pHf->earnings);
	}
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateBusinessHappyFarmPacket(WorldPacket *packet, uint8 result, uint8 type, 
									const uint32 &farmId, const String &strName, uint16 number, uint32 getCoins)
{
	packet->clear();
	packet->SetOpcode(SMSG_HAPPYPRAIRIE_BUY);
	*packet << uint16(SMSG_HAPPYPRAIRIE_BUY) << uint16(0);	
	*packet << uint8(result);
	*packet << uint8(type);
	*packet << farmId;
	AppendPacketString<uint8>(packet, strName);
	*packet << uint16(number);
	*packet << uint32(getCoins);
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateGivingHappyFarmPacket(WorldPacket *packet, uint8 result, uint32 farmId, uint32 destPId, String strNick)
{
	packet->clear();
	packet->SetOpcode(SMSG_GIVE_PRAIRIE);
	*packet << uint16(SMSG_GIVE_PRAIRIE) << uint16(0);	
	*packet << uint8(result);
	*packet << uint32(farmId);
	*packet << uint32(destPId);
	AppendPacketString<uint8>(packet, strNick);	
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateGivingRecodePacket(WorldPacket *packet, uint32 platformId)
{	
	packet->clear();
	packet->SetOpcode(SMSG_GIVE_PRAIRIE_RECORD);
	*packet << uint16(SMSG_GIVE_PRAIRIE_RECORD) << uint16(0);	
	std::list<GameLog> lstGameLogs;
	char strSql[512] = "";
	sprintf(strSql, "UNIX_TIMESTAMP(create_time) >= %u AND (`src_id` = %u OR `platform_id` = %u) AND `type` = %u order by `create_time` DESC", 
			uint32(time(0)-sXmlDataMgr.GetConfXMLValue("HF_RECODE_TIME")), platformId, platformId, en_Operate_HappyFarm);			
	sChannelMgr.getRawCenterLogList(&lstGameLogs, 0, sXmlDataMgr.GetConfXMLValue("HF_RECODE_COUNT"), strSql);
	*packet << uint8(lstGameLogs.size());
	std::list<GameLog>::iterator iter, enditer = lstGameLogs.end();
	for (iter = lstGameLogs.begin(); iter != enditer; ++ iter)
	{
		GameLog &log = *iter;
		uint8 sub_type = 0;
		uint32 pid = 0;
		String szNick = "";		
		if (log.src_id && log.platform_id)
		{// 收取和赠送
			if (log.src_id == platformId)
			{
				sub_type = 2;
				pid = log.platform_id;
				szNick = log.sdata1;
			}
			else
			{
				sub_type = 3;
				pid = log.src_id;
				szNick = log.user_nick;
			}
		}
		else if (log.src_id == 0)
		{// 买
			sub_type = 0;			
		}
		else
			sub_type = 1;
		*packet << (uint8)sub_type
				<< (uint32)pid;
		AppendPacketString<uint8>(packet, szNick);
		*packet << (uint8)log.data1;
		AppendPacketString<uint8>(packet, log.sdata2);
		*packet << (uint16)log.data2;
		*packet << (uint32)log.data3;
		AppendPacketString<uint8>(packet, log.create_time);
	}	
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateBuyFarmListPacket(WorldPacket *packet)
{
	packet->clear();
	packet->SetOpcode(SMSG_BUYHAPPYFARM_LIST);
	*packet << uint16(SMSG_BUYHAPPYFARM_LIST) << uint16(0);	
	std::map<uint32, HappyFarm> mapHappyFarm;
	sXmlDataMgr.GetHappyFarmList(mapHappyFarm);
	*packet << uint8(mapHappyFarm.size());
	std::map<uint32, HappyFarm>::iterator mapi, endmapi = mapHappyFarm.end();
	for (mapi = mapHappyFarm.begin(); mapi != endmapi; ++ mapi)
	{
		*packet << (uint8)mapi->second.model_id
				<< (uint32)mapi->second.price
				<< (uint8)mapi->second.feeding_cycle
				<< (uint32)mapi->second.earnings;
		AppendPacketString<uint8>(packet, mapi->second.szName);
	}
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::CreateSingleFarmPacket(WorldPacket *packet, const HappyFarmItem &hfi)
{
	packet->clear();
	packet->SetOpcode(SMSG_SINGLEHAPPYFARM_LIST);
	*packet << uint16(SMSG_SINGLEHAPPYFARM_LIST) << uint16(0);	
	const HappyFarm* pHf = sXmlDataMgr.GetHappyFarm(hfi.model_id);
	if (pHf == NULL)
		return false;
	uint32 nt = time(0);
	*packet << uint32(hfi.id)
			<< uint8(hfi.model_id);
	AppendPacketString<uint8>(packet, pHf->szName);
	*packet << uint32(nt);
	*packet << uint32(hfi.begin_time);	
	*packet << uint32(hfi.end_time);
	*packet << uint32(pHf->price);
	*packet << uint32(pHf->earnings);
	packet->SetLength(packet->size());
	return true;
}
//-------------------------------------------------------------------
bool 	CenterBankManager::HappyFarmLog(const uint32 &src_id, const String &src_nick, const uint32 &dest_id, const String &dest_nick,
					const uint32 &farmModelId, const String &szName, const uint32 &number, const uint32 &coins)
{
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return false;
	}
	
	pLog->status = 1;
	pLog->type = en_Operate_HappyFarm;
	pLog->src_id= src_id;
	pLog->user_nick = src_nick;
	pLog->platform_id = dest_id;
	pLog->sdata1 = dest_nick;
	pLog->data1 = farmModelId;
	pLog->sdata2 = szName;
	pLog->data2 = number;
	pLog->data3 = coins;		
	pLog->create_time = sTools.GetCurDateTime();
	sChannelMgr.addCenterLogDB(pLog);
	sChannelMgr.freeDumyCenterLog(pLog);
	return true;
}

// 出售全部动物
void CenterBankManager::SellAllFarm(UserPtr & pUser)
{
	if(pUser.isNull())
		return ;
	
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return ;
	
	GameBank bank;
	GetPublicData(pUser, &bank);
	
	std::list<HappyFarmItem> lstHFI;
	HappyFarmJsonToStruct(bank.sdata2, &lstHFI);
	
	if(lstHFI.empty())
		return ;
	
	uint32 nt = time(0);
	std::list<HappyFarmItem>::iterator iter, enditer = lstHFI.end();
	for (iter = lstHFI.begin(); iter != enditer; ++ iter)
	{
		HappyFarmItem &hfi = *iter;
		const HappyFarm* pHf = sXmlDataMgr.GetHappyFarm(hfi.model_id);
		if (pHf == NULL)
			continue;
		
		uint32 getCoins = pHf->price;
		
		if (nt >= hfi.end_time){
			getCoins += pHf->earnings;
		}
		
		Log.Debug("CenterBankManager::SellAllFarm","char[%u] model_id[%u] price[%u] getCoins[%u]",
										pChr->getHandle(),hfi.model_id,pHf->price,getCoins);
		
		//加钱记日志
		sGLMgr.addItemNum(pChr, ItemModel_Coins, getCoins);
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_HappyFarm, ItemModel_Coins, en_UNT_Add, getCoins, pHf->model_id);
	}
	
	bank.sdata2 = "";
	SaveHappyFarmDB(bank);
}

// 更新组局行踪数据
void CenterBankManager::UpdateZujuTrackInfo(CharPtr & pChr, const uint32 & cb_id, const uint32 & game_id, const uint32 & gz_id, String join_code)
{
	if(pChr.isNull())
		return ;
	
WGS_ZUJUTRACK_LOCK
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	GameBank pubData;
	GetPublicData(pUser, &pubData);
	
	Json::Value val;
	
	val["cb_id"] = cb_id;
	val["game_id"] = game_id;
	val["gz_id"] = gz_id;
	val["join_code"] = join_code;
	
	Json::StyledWriter styWriter;
	pubData.sdata3 = styWriter.write(val);
	
	SaveZujuTrackInfo(pubData);
	
	/* WorldPacket packet;
	if(CreateZujuTrackInfoPacket(&packet, cb_id, game_id, gz_id, join_code))
		sGLMgr.SendProtocolsToChr(pChr, &packet); */
}

// 清空组局行踪数据
void CenterBankManager::CancelZujuTrackInfo(CharPtr & pChr)
{
	if(pChr.isNull())
		return ;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	GameBank pubData;
	GetPublicData(pUser, &pubData);
	
	pubData.sdata3 = "";
	SaveZujuTrackInfo(pubData);
	
	// 发送玩家行踪
	WorldPacket packet;
	if(CreateZujuTrackInfoPacket(&packet, 0, 0, 0, ""))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
}

// 获取组局行踪数据
void CenterBankManager::GetZujuTrackInfo(CharPtr & pChr)
{
	if(pChr.isNull())
		return ;
	
WGS_ZUJUTRACK_LOCK		
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return ;
	
	GameBank pubData;
	GetPublicData(pUser, &pubData);
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(pubData.sdata3, val);
	
	uint32 cb_id = 0;
	uint32 game_id = 0;
	uint32 gz_id = 0;
	String join_code = "";
	bool bPlaying = false;
	
	if(val.isMember("cb_id"))
		cb_id = val["cb_id"].asUInt();
	
	CenterBattle cb;
	if(sCenterBattleMgr.GetCenterBattle(cb_id, &cb))
	{
		Log.Debug("CenterBankManager::GetZujuTrackInfo","cb_id[%u] find centerbattle!", cb_id);
		if(cb.status != enBattleStatus_Delete)
		{
			Log.Debug("CenterBankManager::GetZujuTrackInfo","cb_id[%u] status[%u]", cb_id, cb.status);
			Json::Reader reader;
			Json::Value valP;
			reader.parse(cb.player, valP);
			
			for(Json::Value::iterator iterVal=valP.begin(); iterVal!=valP.end(); ++iterVal)
			{
				if(pChr->getHandle() == (*iterVal)["cid"].asUInt())
				{
					if((*iterVal)["player_status"] == enCenterBattlePlayerStatus_Playing)
					{
						bPlaying = true;
					}
					
					break;
				}
			}
			
			if(val.isMember("game_id"))
				game_id = val["game_id"].asUInt();
			
			if(val.isMember("gz_id"))
				gz_id = val["gz_id"].asUInt();
			
			if(val.isMember("join_code"))
				join_code = val["join_code"].asString();
			
			WorldPacket packet;
			if(CreateZujuTrackInfoPacket(&packet, cb_id, game_id, gz_id, join_code, bPlaying))
				sGLMgr.SendProtocolsToChr(pChr, &packet);
		}
		else
		{
			Log.Debug("CenterBankManager::GetZujuTrackInfo","cb_id[%u] delete!", cb_id);
			CancelZujuTrackInfo(pChr);
		}
	}
	else
	{
		Log.Debug("CenterBankManager::GetZujuTrackInfo","no cb_id[%u] centerbattle!", cb_id);
		WorldPacket packet;
		if(CreateZujuTrackInfoPacket(&packet, 0, 0, 0, "", false))
			sGLMgr.SendProtocolsToChr(pChr, &packet);
	}
}

// 保存组局行踪数据
void CenterBankManager::SaveZujuTrackInfo(GameBank & pBank)
{
	CenterDatabase.WaitExecute("update game_bank set `sdata3` = '%s' where `bank_id` = %u", pBank.sdata3.c_str(), pBank.bank_id);
}

// 组局行踪信息
bool CenterBankManager::CreateZujuTrackInfoPacket(WorldPacket *packet, 
										const uint32 & cb_id, 
										const uint32 & game_id, 
										const uint32 & gz_id,
										String join_code,
										bool bPlaying)
{
	packet->clear();
	packet->SetOpcode(SMSG_LASTZUJU_TRACKINFO);
	*packet << uint16(SMSG_LASTZUJU_TRACKINFO) << uint16(0)
			<< uint32(cb_id)
			<< uint32(game_id)
			<< uint32(gz_id);
	
	AppendPacketString<uint8>(packet, join_code);
	
	*packet << uint8(bPlaying);
	
	packet->SetLength(packet->size());
	return true;
}
